簡體   English   中英

構造一個對象后,是否與其他線程建立了內存柵欄?

[英]After an object is constructed, is a memory fence established with other threads?

有人可以驗證我對構造函數執行后建立的內存柵欄的理解。 例如,假設我有一個名為Stock的類。

public final class Stock{

       private final String ticker;
       private double qty;
       private double price;

       public Stock ( String ticker, double qty, double price ){
              this.ticker  = ticker;
              this.qty     = qty;
              this.price   = price;

              //I am assuming a memory fence gets inserted here.
       }


       public final void updateQty( double qty ){
           this.qty = qty;
       }


       public final void updatePrice( double price ){
           this.price = price;
       }

}

此外,假設構造是由線程1,然后執行updateQty()updatePrice()線程2(總是由線程2)被稱為若干時間。

我的論點是,在Thread1創建對象之后,對象的“可見性”與jvm中的所有其他線程建立。 由於兩個可變變量僅由Thread2更改,因此我不需要任何鎖定。 我對么?

我的論點是,在Thread1創建對象之后,對象的“可見性”與jvm中的所有其他線程建立。

這是正確的。 沒有隱含的構造函數內存屏障/圍欄,這就是構造函數周圍的指令重新排序是一個問題。 如果您要在構造它的其他線程中使用Stock對象,則必須在調用任何更新方法之前synchronize該對象。

由於兩個可變變量僅由Thread2更改,因此我不需要任何鎖定。

在最初同步Thread2的對象之后,除非您想在其他線程中查看這些變異字段,否則不需要任何其他鎖定。 如果多個線程正在從您的Stock對象讀取而Thread2正在改變它,那么所有線程都需要通過同步或通過使字段變異字段為volatile來穿過內存屏障。

這必須同時使用構造函數操作重新排序內存可見性。 有關構造函數重新排序的更多缺陷,請參閱此答案:

這是對象的安全發布嗎?

很不幸的是,不行。 構造函數(大多數)就像Java內存模型中的常規方法。

但這很糟糕,它給程序員帶來了無盡的困惑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM