2013-05-28 31 views
1

的安全初始化從Java theory and practice: Fixing the Java Memory Model, Part 2非final字段

The new JMM also seeks to provide a new guarantee of initialization safety -- that as long as an object is properly constructed (meaning that a reference to the object is not published before the constructor has completed), then all threads will see the values for its final fields that were set in its constructor, regardless of whether or not synchronization is used to pass the reference from one thread to another.

那麼,什麼是關於構造函數初始化非最終字段?從a reference to the object is not published before the constructor has completed我可以得出結論,行爲與最終字段相同。這是對的嗎?

回答

3

把這個簡單的類:

class Example { 
    final int i; 
    int j; 
    Example() { i = 5; j = 5; } 
} 

對象沒有提到施工期間發佈的,所以JMM保證訪問實例的新創建的實例都讀的線程將看到i = 5。無論實例如何發佈,情況都是如此。

但是,如果實例沒有安全發佈,那些相同的線程可能會看到j = 0(即默認值)。安全出版物成語包括:

  • 從靜態初始化劑
  • 初始化實例標記參考實例作爲揮發性
  • 標記爲最終
  • 的參考實例同步所有訪問
+0

如果'Example'也有volatile變量'c'會怎麼樣?這個變量初始化的行爲如何? –

+1

@michaelnesterenko在'c'的構造函數中設置的值將從其他線程可見。你也可以用它來安全地發佈'j',但是這很容易出錯。 – assylias

1
  • 對於易失性變量,保證寫入對所有線程立即可見。無論寫入是否在構造函數中完成,都是這種情況。

  • 對於非易失性變量,寫入可能不會立即對其他線程可見。無論寫入是否在構造函數中完成,都是這種情況。

一個特殊情況是final字段。一旦構造函數完成,寫入對象的最終字段將保證對所有線程都可見。

您可以閱讀更多here