/*
目標:雙重檢查機制,以及使用volatile修飾(最好,最安全,最推薦)
步驟:
1.構造器私有
2.提供一個靜態變數用于存盤一個單例物件
3.提供一個方法進行雙重檢查機制回傳單例物件
4.使用volatile修飾靜態的變數
雙重檢查的優點:執行緒安全,延遲加載,效率較高!
*/
public class Singleton {
private volatile static Singleton INSTANCE;
private Singleton(){
}
public static Singleton getInstance(){
// 第一次檢查:判斷單例物件的變數是否為null
if(INSTANCE == null){
synchronized (Singleton.class){
//第二次檢查:判斷單例物件的變數是否為null
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
為什么要使用volatile修飾呢?
-
禁止指令重排序
創建物件要經過如下幾個步驟
a. 分配記憶體空間
b. 呼叫構造器,初始化實體
c. 回傳地址給參考但是JVM具有指令重排的特性,執行的順序有可能變成 a-c-b,指令重排在單執行緒下不會出現問題,但是在多執行緒下會導致一個執行緒獲得還沒有初始化的實體,例如:執行緒T1執行了a,b,此時執行緒T2呼叫getInstance()方法發現INSTANCE不為null,因此回傳INSTANCE,但此時INSTANCE還未被初始化,
-
保證可見性
由于可見性問題,執行緒T1在自己的作業執行緒內創建了實體,但此時還未同步到主記憶體中,此時執行緒T2判斷INSTANCE還是null,那么執行緒T2又將在自己的作業執行緒創建一個實體,這樣就創建了多個實體如果加上了volatile修飾INSTANCE之后,保證了可見性,一旦執行緒T1回傳了實體,執行緒T2可以立即發現INSTANCE不為null
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/236025.html
標籤:其他
下一篇:記錄解決select into outfile&load data報錯ERROR 1(Errcode: 13 - Permission denied)
