執行緒安全的懶漢模式為什麼要使用volatile關鍵字
阿新 • • 發佈:2018-12-08
來看這樣一段程式碼,為什麼一定要用volatile關鍵字修飾instance變數呢?
public class Singleton{
private static volatile Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null){
synchronized(Singleton.class){
if(instance==null){
instance=new Singleton ();
}
}
}
return instance;
}
}
instance=new Singleton();這條語句並不是一個原子操作
-
分配記憶體給物件;
-
物件的初始化;
-
將分配好物件的地址指向instance變數,即instance變數的寫;
設想一下,如果不使用volatile關鍵字限制指令的重排序,1-3-2操作,獲得到單例的執行緒可能拿到了一個空物件!
總結一下volatile對重排序的限制 -
當第二個操作是volatile寫,前面的操作都不能重排序,即volatile寫之前的操作不會重排序到volatile後
-
volatile讀之後的操作,不會重排序到volatile讀之前
-
第一個操作是volatile寫,第二個操作volatile讀,不會重排序