單例模式在設計模式中比較常見,在多線程通路的時候容易出現線程不安全的隐患
懶漢式(延遲加載)/餓漢式(立即加載)
直接給出雙檢查鎖單例模式
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance(){
if (instance == null){
synchronized(Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
問題根源在此: new對象可拆分成3個指令執行 1、memory = allocate() //配置設定記憶體
2、ctorInstance(memory) //初始化對象
3、instance = memory //instance指向剛配置設定的記憶體位址
其中2和3可能會指令重排,如果發生指令重排,先執行了指令3,此時線程2執行第一個if判斷時就是false,此時直接傳回一個沒有初始化的instance對象,導緻系統錯誤
是以應加上volatile禁止重排序
public class Singleton {
private volatile static Singleton instance;
private Singleton (){
}
public static Singleton getInstance(){
if (instance == null){
synchronized(Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}