單例模式
Java中的設計模式總結來說至少有23種,而單例模式是其中最簡單且最常用的設計模式之一。
單例模式有兩種常見的類型,一種是餓漢式,一種是懶漢式。
單例模式的特點
1. 單例類只能有一個實例並且由自己創建
2. 單例類必須給其他所有對象提供這一實例
單例模式的應用場景
無論是應用層軟件或者是底層服務,經常需要用到單例模式的特點,比如線程池,緩存,日誌,對話框,打印機的驅動程序等等。
懶漢式單例模式
//懶漢式單例類.在第一次調用的時候實例化自己
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//靜態工廠方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
爲了避免單例類被外部直接new出來,應當把構造方法私有化,只能通過getInstance()來訪問。雖然實際上即使通過構造方法私有化,在外部仍然可以通過反射等手段創建出這個類的對象。不過這個問題在此不深入探討,有興趣的朋友可以瞭解下Java的反射機制。
以上的代碼在多線程操作的過程中仍然可能出現問題,解決方法是加上同步操作。
代碼如下:
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
但是實際上面這種加上同步的方法效率比較低,因爲無論哪個線程getInstance的時候都會進行同步,因此最好是當實例已經存在的時候直接返回而不加同步,若不存在需要創建的時候再進行同步,因此優化後的代碼如下:
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
餓漢式模式
所謂餓漢式即在類創建的時候就同時new出來一個靜態的實例,供外部使用,因此保證線程安全。
代碼如下:
//餓漢式單例類.在類初始化時,已經自行實例化
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//靜態工廠方法
public static Singleton1 getInstance() {
return single;
}
}