經過單例模式能夠保證系統中一個類只有一個實例並且該實例易於被外界訪問,從而方便對實例個數的控制並節約系統資源。若是但願在系統中某個類的對象只能存在一個,單例模式是最好的解決辦法。java
對系統中某些類來講,只有一個實例很重要,例如,一個系統只能有一個窗口管理器或文件系統。所以確保系統中某個對象的惟一性即一個類只能有一個實例很重要。函數
單例模式確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例,這個類稱爲單例類,它提供全局訪問方法。單例模式有三個要點:一是某個類只能有一個實例;二是它必須自行建立這個實例;三是它必須自行向整個系統提供這個實例。線程
單例模式的目的是保證類僅有一個實例,並提供一個訪問它的全局訪問點。單例類擁有一個私有構造函數,確保用戶沒法經過new關鍵字直接實例化。除此以外,該模式包含一個靜態私有成員變量與靜態公有的工廠方法,該工廠方法負責校驗實例存在性並實例化本身,而後存儲在靜態成員變量中,以確保只有一個實例被建立。所以在單例模式的實現過程當中要注意三點:code
public class Singleton { private static Singleton instance = null; //私有構造方法 private Singleton() { } //靜態公有工廠方法,返回惟一實例 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
public class Client { public static void main(String[] args) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2); } }
在定義靜態變量的時候實例化單例類,在類加載的時候就已經建立了單例對象。在這個類被加載時,靜態變量instance會被初始化,此時類的私有構造函數會被調用,單例類的惟一實例將被建立。對象
public class EagerSingleton { private static final EagerSingleton instance = null; private EagerSingleton() { } public static EagerSingleton getInstance() { return instance; } }
懶漢式單例類不是在定義靜態變量時實例化單例類,而是在調用靜態工廠方法時實例化單例類,所以在類加載時並無建立單例對象。blog
public class LazySingleton { private static LazySingleton instance = null; private LazySingleton() { } public static LazySingleton getInstance() { if(instance == null) { instance = new LazySingleton(); } return instance; } }
從資源利用效率角度來講,懶漢式單例類比餓漢式單例類稍好。從速度和反應時間角度來講,餓漢式單例類比懶漢式稍好。然而,懶漢式單例類在實例化時,必須處理好多個線程同時首次引用此類時的訪問限制問題。圖片