單例模式:建立獨一無二的物件
單例模式(Singleton Pattern): 用來建立獨一無二的,只能有一個例項的物件的入場券。
作用:有些物件我們只需要一個,比如:執行緒池、快取、對話方塊、處理偏好設定、登錄檔等物件,這些物件只能有一個例項,如果製造出多個例項,就會導致很多問題產生,例如:程式行為異常、資源使用過量、或者是不一致的結果。
當我們建立一個物件的時候,只需要new MyObject()即可。假設有這麼一個類,我們需要保證只能夠例項化它一次,那麼該如何實現呢?
可以這麼做:讓這個類含有一個私有構造器,使得除本身之外的所有類都不能夠對其例項化。在MyClass定義一個私有構造器,一個靜態方法getInstance(),使用MyClass.getInstance()方法呼叫得到一個例項物件。
public MyClass{
private MyClass(){}
public static MyClass getInstance(){
return new MyClass();
}
}
一個經典的單例模式實現(延遲例項化----懶漢式):
package com.designPattern; public class Singleton { //利用一個靜態變數來記錄Singleton類的唯一變數 private static Singleton uniqueInstance; //把構造器宣告為私有的,只有在Singleton類裡才能呼叫構造器 private Singleton(){} //getInstance()方法例項化物件,並返回這個例項 public static synchronized Singleton getInstance(){ if(uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } }
這樣就可以保證Singleton物件是獨一無二的,利用單例模式建立而得。當前類沒有公開的構造器,因為它的構造器被宣告為私有的,別人不可能通過new產生多個物件,如何要取得例項,必須發起"請求"得到一個例項,而不是自行例項化得到一個例項。
該類有一個靜態方法,叫做getInstance()。呼叫這個方法,該例項立刻現身,隨時可以工作。事實上,這個例項物件可能是在這次呼叫的時候被創建出來的,也可能是以前很早就被創建出來了。
何為懶漢式:當JVM載入這個類時並沒有立即建立此唯一的單件例項,而是在使用到的時候才建立。
用類圖表示:
另一種實現方式("急切"建立例項:餓漢式):
public class Singleton{
//在靜態初始化器中建立單件,保證執行緒安全
private static Singleton uniqueInstance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return uniqueInstance; //已經有了例項,直接使用它
}
}
利用這個做法,依賴JVM在載入這個類時馬上建立唯一的單件例項。JVM保證在任何執行緒訪問uniqueInstance靜態變數之前,一定先建立此例項。
單例模式----確保一個類只有一個例項,並提供一個全域性訪問點。