設計模式 之 單例 模式

設計模式是開發中很重要的一種思想,今天記錄一下單例模式,備忘,哈哈。

first 懶漢式 + 雙重校驗鎖 + 禁止指令重排序優化

public class SingletonOne {

// volatile 禁止指令重排序優化
private static volatile SingletonOne instance = null;

private SingletonOne() {

}

// synchronized 修飾的同步方法比一般的方法要慢很多。所以此處使用雙重校驗鎖。
public static SingletonOne getInstance() {
    if (null == instance) {
        synchronized(SingletonOne.class) {
            if (null == instance) {
                instance = new SingletonOne();
            }
        }
    }
    return instance;
}}

second 餓漢式 不推薦

public class SingletonTwo {

private static SingletonTwo instance = new SingletonTwo();

private SingletonTwo() {

}

public static SingletonTwo getInstance() {
    return instance;
}}

third 靜態內部類加載

public class SingletonThree {

private SingletonThree() {

}

private static class SingletonHolder {
    public static SingletonThree instance = new  SingletonThree();
}

public static SingletonThree getInstance() {
    return SingletonHolder.instance;
}}

fourth 枚舉 目前最爲安全的實現單例的方法是通過內部靜態enum的方法來實現,因爲JVM會保證enum不能被反射並且構造器方法只執行一次。

public class SingletonFour {
private SingletonFour() {

}

private static enum Singleton{
    INSTANCE;

    private SingletonFour instance;

    private Singleton() {
        instance = new SingletonFour();
    }

    public SingletonFour getInstance() {
        return instance;
    }

}

public static SingletonFour getInstance() {
    return Singleton.INSTANCE.instance;
}}



上面提到的三種實現單例的方式都有共同的缺點:
1.需要額外的工作來實現序列化,否則每次反序列化一個序列化的對象時都會創建一個新的實例。
2.可以使用反射強行調用私有構造器(如果要避免這種情況,可以修改構造器,讓它在創建第二個實例的時候拋異常)。

而枚舉類很好的解決了這兩個問題,使用枚舉除了線程安全和防止反射調用構造器之外,還提供了自動序列化機制,
防止反序列化的時候創建新的對象。因此,《Effective Java》作者推薦使用的方法。不過,在實際工作中,很少看見有人這麼寫。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章