Java的設計模式,大體上可以分爲23種類型,今天淺談下單例模式。
單例模式,顧名思義,只有一個實例。單例的實現有兩種,叫餓漢式和懶漢式。
1、餓漢式--顧名思義,很飢餓,不管你有沒有調用,我類加載的時候就直接生成一個單例。這個模式是線程安全的。代碼如下:
public class EagerSingleton {
private static EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return instance;
}
}
說明:
①instance屬性必須是private static的。保證兩點:1、不能能被外部調用,2、類加載的時候就會執行,就會生成一個實例。
②getInstance方法必須是static的。兩點原因:1、因爲instance是static的,所以方法必須是static的,2、只能通過類調用方法,不能通過實例對象.方法的形式去調用。
③必須要有一個私有化的構造器,是爲了防止new一個新的對象。
2、懶漢式--顧名思義,比較懶,調用的時候纔會去生成實例。線程不安全的,代碼如下:
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() { }
public static LazySingleton getInstance() {
if (instance = null) {
instance = new LazySingleton();
}
return instance;
}
}
說明:
①private 和 static的修飾和餓漢式的原因一樣。
②如果是多線程系統,此處是線程不安全的。分析:有A、B兩個線程來調用getInstance方法,線程A判斷了if條件之後,線程掛起了。這個時候B線程進來了,走到if判斷那裏,判斷爲true,然後繼續向下走。這個時候先new了一個對象出來,然後返回了。這個時候A線程繼續向下執行,就會再次new一個對象出來。這樣,這個對象就不是單例了。
優化:
在if判斷的時候,加上同步鎖,代碼如下:
synchronized (LazySingleton.class) {
if (null == instance) {
instance = new LazySingleton();
}
}
加上synchronized 鎖之後,就是線程安全的了,只會new 出一個實例來。