Java設計模式 - 單例模式

目錄

一、介紹

1.定義

2.角色

3.特點

二、實現

1.餓漢式(線程安全)

2.懶漢式

3.懶漢式(雙重檢查加鎖版本)

4. 枚舉方式

5.靜態內部類


一、介紹

1.定義

確保類只有一個實例,並提供一個全局訪問點。

2.角色

  • Singleton:單例類

3.特點

  • 優點:因爲系統內存中只有一個實例,可以節約系統資源,並且減少了因爲創建、銷燬對象帶來的損耗,提高了系統的性能。
  • 缺點:該模式沒有抽象層,不易於擴展,且違背了“單一職責原則”,既負責實例的創建,又包含了一些業務方法。

二、實現

1.餓漢式(線程安全)

public class Singleton {

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

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

在加載類時即創建唯一的單例實例,不管用不用,先創建再說。若一直未被使用,則浪費了空間,但因爲每次調用時無需判斷,節省了運行時間,以空間換時間。

2.懶漢式

public class Singleton {

    private static Singleton instance;
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance =  new Singleton();
        }
        return instance;
    }
}

在第一次使用實例時才創建。該方式是線程不安全的,在多個線程同時訪問getInstance方法時會出現問題,可在getInstance方法使用synchronized關鍵字解決該問題。但每次調用該方法時都要先獲取鎖,可能會增加運行時間,還會造成阻塞。

3.懶漢式(雙重檢查加鎖版本)

public class Singleton {

    private volatile static Singleton instance;
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null)
                    instance = new Singleton();
            }
        }
        return instance;
    }
}

只有在第一次創建實例時纔會進入synchronized塊,減少了getInstance方法的運行時間。同時採用了volatile關鍵字保持數據的可見性以及防止指令重排。

4. 枚舉方式

public enum Singleton {

    INSTANCE;
    public void doSomething() {
    }
}

枚舉創建實例是線程安全的,因此該方法既簡潔又安全,但可讀性不高,較少用。

5.靜態內部類

public class Singleton {

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton() {}

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

在顯式調用getInstance方法時纔會裝載SingletonHolder類,從而初始化實例,因此是線程安全的。

 

參考:

1. 《Head First 設計模式》

2. 《圖說設計模式》 https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/singleton.html

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