(1)雙重校驗鎖緩存
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
1)構造函數和對象私有化函數
2)對象用violate和static關鍵字修飾spa
3)公有的靜態獲取對象方法線程
4)雙重校驗鎖code
violate關鍵字做用:防止指令重排序對象
volatile變量能夠確保將變量的更新操做通知到其餘線程。當把變量聲明爲volatile類型後,編譯器與運行時都會注意到這個變量是共享的,依次不會將該變量上的操做與其餘內存操做一塊兒重排序。volatile變量不會被緩存到寄存器或者對其餘處理器不可見的地方,所以在讀取volatile類型的變量時總會返回最新寫入的值。blog
建立對象能夠分解爲以下的3行僞代碼排序
memory=allocate(); //1:分配對象的內存空間內存
ctorInstance(memory); //2:初始化對象get
instance=memory; //3:設置instance指向剛分配的內存地址
上面3行代碼中的2和3之間,可能會被重排序致使先3後2
(2)靜態內部類
public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }
1)對象用static和final修飾
2)對象由靜態類包裹