單實例懶漢模式幷包保證成功

a) public static Singleton getInstance() {  

b)         if (instance == null) {  

c)             synchronized (instance) {  

d)                 if (instance == null) {  

e)                     instance = new Singleton();  

f)                 }  

g)             }  

h)         }  

i)         return instance;  

j)     }  

Java指令中創建對象和賦值操作是分開進行的,也就是說 instance=new Singleton()是分兩步進行的。但是jvm並不保證這兩個操作的先後順序,也就是說有可能會jvm會爲新的Singleton實例分配空間,然後直接賦值給instance成員,然後再去初始化這個Singleton實例。

這樣上面的代碼就可能會出現下面的錯:

a>AB線程同時進入了第一個if判斷

b>A首先進入synchronized塊,由於instancenull,所以它執行instance = new Singleton();

c>由於JVM內部的優化機制,JVM先畫出了一些分配給Singleton實例的空白內存,並賦值給instance成員(注意此時JVM沒有開始初始化這個實例),然後A離開了synchronized塊。

d>B進入synchronized塊,由於instance此時不是null,因此它馬上離開了synchronized塊並將結果返回給調用該方法的程序。

e>此時B線程打算使用Singleton實例,卻發現它沒有被初始化,於是錯誤發生了

此時的問題是:有可能instance不是null但是沒有被初始化的情況。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章