單例

靜態(tài)類內(nèi)部加載
使用內(nèi)部類的好處是,靜態(tài)內(nèi)部類不會在單例加載時就加載,而是在調(diào)用getInstance()方法時才進(jìn)行加載,達(dá)到了類似懶漢模式的效果,而這種方法又是線程安全的。

public class SingletonDemo { private static class SingletonHolder{ private static SingletonDemo instance=new SingletonDemo();
    } private SingletonDemo(){
        System.out.println("Singleton has loaded");
    } public static SingletonDemo getInstance(){ return SingletonHolder.instance;
    }
}

double check volatile

private volatile Resource resource;

public Resource getResource() {
  Resource tmp = this.resource;  
  if (tmp == null) {   
    synchronized(this){
      tmp = this.resource   
      if (tmp == null) {  
        this.resource = tmp = new Resource();    
      }     
    }    
  }  
  return tmp;  
} 

new Resource() 可以分解為:

 memory =allocate();     //1:分配對象的內(nèi)存空間 
 ctorInstance(memory);   //2:初始化對象 
 instance =memory;       //3:設(shè)置instance指向剛分配的內(nèi)存地址

如果被重排為

 memory = allocate();     //1:分配對象的內(nèi)存空間 
 instance = memory;       //2:設(shè)置instance指向剛分配的內(nèi)存地址
 ctorInstance(memory);   //3:初始化對象 

就會出現(xiàn)線程A中執(zhí)行這段賦值語句,在完成對象初始化之前就已經(jīng)將其賦值給resource引用,恰好另一個線程進(jìn)入方法判斷instance引用不為null,然后就將其返回使用,導(dǎo)致出錯。將resource設(shè)置為volatile之后,可以保證對相關(guān)操作的順序。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容