單例模式確保某個類只有一個實例,並且自行實例化並向整個系統提供這個實例。java
餓漢式
public class Singleton{ private static Singleton instance=new Singleton(); //私有構造器,防止被屢次new建立 private Singleton(){} public static Singleton getInstance(){ return instance; } }
靜態內部類
public class Singleton{ //私有構造器,防止被屢次new建立 private Singleton(){} //把instance的實例放到靜態類內部 private static class SingletonInstance{ private static final Singleton instance=new Singleton(); } //調用getInstance方法時加載靜態內部類 public static Singleton getInstance(){ return SingletonInstance.instance; } )
雙重檢查(推薦)
public class Singleton{ //volatile關鍵字確保多個線程正確地處理instance變量 private volatile static Singleton instance; //私有構造器,防止被屢次new建立 private Singleton(){} piblic static Singleton getInstance(){ //第一次檢查 if(instance==null){ synchronized(Singleton.class){ //第二次檢查 if(instance==null){ instance=new Singleton(); } } } return instance; } }
爲何instance須要用volatile修飾?
由於new Singleton()可能會發生重排序,具體能夠分爲三個步驟:
一、爲對象分配內存
二、初始化對象
三、讓instance指向內存地址
這種狀況下可能會發生重排序,也就是變成1——>3——>2(單線程下並無改變結果,因此這是容許的,可是多線程下可能會返回未初始化的instance),所以須要volatile禁止重排序多線程