標籤:速度 變數 建立型 建立型模式 public 對象建立 比較 系統開發 bsp
單例模式是一種對象建立型模式,使用單例模式,可以保證為一個類只產生唯一的一個執行個體對象。也就是說,在整個程式空間中,該類只存在一個執行個體對象。
其實,GoF對單例模式的定義是:保證一個類,只有一個執行個體存在,同時提供能對該執行個體加以訪問的全域存取方法。
那麼,我們為什麼要用單例模式呢?
這是因為在應用系統開發時,我們常常有以下需求:
1、在多個線程之間,比如servlet環境,共用同一個資源或者操作同一個對象。
2、在整個程式空間使用全域變數,共用資源。
3、在大規模系統中,為了效能的考慮,需要節省對象的建立時間等等。
因為單例模式可以保證為一個類只產生唯一的執行個體對象,所以這些情況,單例模式就派上用場了。
單例模式分為幾種情況
1、餓漢式(在類載入時就完成了初始化,所以類載入比較慢,但擷取對象的速度快,同時無法做到延時載入)
public class Person { public static final Person person = new Person(); //建構函式私人化 private Person(){} //提供一個全域的靜態方法 public static Person getPerson(){ return person; }}
2、接下來是懶漢式(在類載入時不初始化,可以延時載入)
懶漢式可以分為兩種,一種安全執行緒,一種線程不安全
(1)懶漢式(線程不安全,但效率高)
public class Person { public static Person person = null; //建構函式私人化 private Person(){} //提供一個全域的靜態方法 public static Person getPerson(){ if(person == null){ person = new Person(); } return person; }}
(2)懶漢式(安全執行緒,但效率低)
1 public class Person { 2 public static Person person = null; 3 4 //建構函式私人化 5 private Person(){} 6 7 //提供一個全域的靜態方法 8 public static synchronized Person getPerson(){ 9 if(person == null){10 person = new Person();11 }12 return person;13 }14 }
3、靜態內部類(可以延時載入)
這種方法是餓漢式的一種升級,這種方式同樣利用了classloder的機制來保證初始化instance時只有一個線程,同時實現了延時載入
1 public class Person { 2 private static class PersonHolder{ 3 private static final Person person = new Person(); 4 } 5 6 //建構函式私人化 7 private Person(){} 8 9 //提供一個全域的靜態方法 10 public static final Person getPerson(){11 return PersonHolder.person;12 }13 }
4、雙重檢查(對懶漢式的升級,效率更高)
public class Person { public static Person person = null; //建構函式私人化 private Person(){} //提供一個全域的靜態方法 public static Person getPerson(){ if(person == null){ synchronized(Person.class){ if(person == null){ person = new Person(); } } } return person; }}
這樣寫,只把建立執行個體的代碼放到同步鎖中,為了保證安全執行緒再在同步鎖中加一個判斷,雖然看起來更繁瑣,但是同步中的內容只會執行一次,執行過後,以後經過外層的if判斷後,都不會在執行了,所以不會再有阻塞。程式啟動並執行效率也會更加的高。
java設計模式------4、單例模式