[ 設計模式筆記 ] 3.單例模式

單例模式

總結:

在這裏插入圖片描述


介紹

        保證在整個軟件系統中,對某個類對象只能存在一個實例,並且提供一個取得其對象實例的方法。


餓漢式

靜態常量方式

實現

        構造器私有化,屬性位置創建實例的靜態變量, 提供靜態方獲取靜態實例。

public class Single {
    // 構造器私有化
    private Single(){}

    // 靜態實例
    private final static Single instance = new Single();

    // 靜態方法獲取
    private static Single getInstance() {
        return instance;
    }
}

優點:

        寫法比較簡單,在類裝載的時候就完成了實例化。避免了線程同步問題。

缺點:

        在類裝載的時候完成實例化,沒有達到Lazy Loading的效果,如果從始至終沒有使用過這個實例,則會造成內存的浪費

結論:

靜態代碼塊兒方式

        這種方式也是在類加載時候進行實例的new, 因此優點和缺點和靜態常量方式一致。

實現

package club.fsociety.singleton;

public class Single2 {
    // 構造器私有化
    private Single2(){ }

    // 靜態實例
    private static Single2 instance;

    // 靜態代碼快兒
    static {
        instance = new Single2();
    }

    // 靜態方法獲取
    private static Single2 getInstance() {
        return instance;
    }
}

懶漢式

        解決Lazy Loading的問題。

線程不安全的方式

實現:

package club.fsociety.singleton;

public class Single3 {

    // 私有構造器
    private Single3(){}

    // 靜態成員
    private static Single3 instace;

    // 獲取實例的方法
    private static Single3 getInstace() {
        if(null == instace)
            instace = new Single3();
        return instace;
    }
}

優點:

         實現了Lazy Loading

缺點:

         線程不安全,可能多個線程同時判定爲未創建,後進行創建,會導致多創建出來幾個實例。

結論:

         瞭解其存在的問題,開發中不要使用

線程安全方式:

實現

         使用了同步代碼塊來修飾獲取實例的方法:

package club.fsociety.singleton;

public class Single3 {

    // 私有構造器
    private Single3(){}

    // 靜態成員
    private static Single3 instace;

    // 獲取實例的方法
    private static synchronized Single3 getInstace() {
        if(null == instace)
            instace = new Single3();
        return instace;
    }
}

優點

         即解決了餓漢中存在的Lazy Loding問題,又解決了線程安全問題。

缺點

         getInstance方法頻繁調用下會導致效率地下。

結論

         在實際開發中不推薦使用。


DoubleCheck

實現

package club.fsociety.singleton;

public class Single4 {

    // 私有構造器
    private Single4(){}

    // 靜態成員
    private static Single4 instace;

    // 獲取實例的方法
    private static  Single4 getInstace() {
        if(null == instace) {
            synchronized (Single4.class) {
                if(null == instace)
                    instace = new Single4();
            }
        }
        return instace;
    }
}

優點

   &nbsp    即解決了Lazy Loading 和 線程安全問題,又避免每次getInstance的時候都執行一遍同步代碼塊兒。

缺點

   &nbsp    

結論:

        強烈推薦使用。


靜態內部類方式

實現方式

        外部類被裝載的時候,靜態內部類不會被裝載。當調用外部類獲取靜態內部類方法時候再裝載靜態內部類,且靜態內部類被裝載後會初始化靜態代碼,且線程安全。這樣既能解決線程安全問題,也能解決Lazy Loading問題。

package club.fsociety.singleton;

public class Single5 {

    // 私有化的構造
    private Single5(){}

    // 靜態內部類
    private static class Single5Instance {
        private static final Single5 instance = new Single5();
    }

    // 獲取實例方法
    public static Single5 getInstance() {
        return Single5Instance.instance;
    }
}

優點:

        解決線程安全,和LazyLaoding問題,且效率高。

結論

        推薦使用。


枚舉

實現方式:

        JDK1.5中添加的枚舉來實現單例模式,因爲枚舉當中的每個枚舉元素本聲就是自身的一個實例的單例,剛好可以直接藉助來實現單例模式。

public enum Single6 {
    INSTANCE;
    public void method() {
        System.out.println("這是一個實例方法");
    }
}

優點

        能避免多線程同步問題,而且還能防止反序列化重新創建的對象。其爲最推薦的方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章