1. 程式人生 > >設計模式之【單例模式】

設計模式之【單例模式】

sta 嵌套 mem ont volatile 單例對象 locate 頂級 調用

完美的單例

雙重檢查鎖(DCL

用處:延遲初始化,降低同步開銷。double checked locking

註意:single必須聲明為volatile,且支持JDK1.5及以上版本。

對象初始化需要三個步驟:

memory=allocate(); //1.分配內存空間

ctorInstance(memory) //2.初始化對象

instance=memory //3.設置對象指向分配的內存

如果single不是volatile的話,那麽處理器會有可能重排序2 3步驟,導致多線程並發時得到實例已經分配內存空間,但並未初始化。

Volatile保證了單例對象的原子性、可見性,禁止了步驟

2 3的重排序。

public class Singleton {

 

private volatile static Singleton single;

private Singleton(){

 

}

 

public static Singleton getInstance() {

if(single==null){

synchronized(Singleton.class){

if(single==null){

single=new Single();

}

}

}

return single;

}

}

靜態內部類單例

好處:JVM在類的初始化階段(即在

Class被加載後,且被線程使用之前),會執行類的初始化。在執行類的初始化期間,JVM會去獲取一個鎖。這個鎖可以同步多個線程對同一個類的初始化。

基於類初始化鎖【是類的初始化,並非對象初始化】的特性,可以以靜態內部類的方式實現延遲初始化單例:

public class Singleton {

private static class SingletonHolder{

public static Singleton single = new Singleton();

}

 

private Singleton(){

 

}

 

public static Singleton getInstance() {

return SingletonHolder.single; } }

初始化一個類,包括執行這個類的靜態初始化和初始化這個類中聲明的靜態字段。根據JAVA規範,當發生如下情況,將初始化一個類:

T是一個類,且T類的一個實例被創建;

T是一個類,且T類中聲明的一個靜態方法被調用;

T中聲明的一個靜態字段被賦值;

T中聲明的一個靜態字段被使用,且這個字段不是一個常量字段;

T是一個頂級類,而且一個斷言語句嵌套在T內部被執行。

枚舉

枚舉是天生的單例。

設計模式之【單例模式】