2010-10-19 45 views
5

在多線程環境中,線程如何可能看到「部分構造的對象」?我知道它不是線程安全的,因爲多個線程可以創建多個實例。非線程安全Singleton中的部分構造對象

class LazyInit 
{ private static Resource resource = null; 

    public static getInstance() 
    { if (resource == null) { resource = new Resource(); } 
     return instance; 
    } 
} 
+1

查看https://secure.wikimedia.org/wikipedia/en/wiki/Double-checked_locking – Bozho 2010-10-19 08:38:28

回答

7

由於亂序寫入。

如果您的構造函數寫入非最終成員,他們不必立即提交到內存,實際上他們甚至可能在單例變量之後被提交。 Java保證影響它的線程按順序看待情緒,但除非你放置內存障礙,否則不會影響其他線程。
有關更多信息,請參閱Java規範的this questionthis page

它可能在旁邊,但在你的例子中,兩個線程完全有可能看到不同的單例。假設一個線程測試變量的無效性,輸入if並在它有機會構造該對象之前被搶佔。現在讓CPU測試尚未空對象的新線程構造了單例。當舊的線程再次開始運行時,它將愉快地完成構建對象並覆蓋單例變量。
如果Resource的構造函數調用最終會導致對此getInstance的另一個調用的方法,則會出現另一個更可怕的問題。即使程序的狀態不會導致無限循環,您也將創建多個單例實例。