天天看點

多線程核心技術-單例模式

單例模式在設計模式中比較常見,在多線程通路的時候容易出現線程不安全的隐患

懶漢式(延遲加載)/餓漢式(立即加載)

直接給出雙檢查鎖單例模式

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; 
     } 
    
 }
           

繼續閱讀