設計模式之單例模式


什么是單例設計模式?

單例模式,是一種常用的軟件設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個實例。即一個類只有一個對象實例。

 

類結構圖

 

 

 

具體實現

需要:

(1)將構造方法私有化,使其不能在類的外部通過new關鍵字實例化該類對象。

(2)在該類內部產生一個唯一的實例化對象,並且將其封裝為private static類型。

(3)定義一個靜態方法返回這個唯一對象。

 

實現一:立即加載 / “餓漢模式”

立即加載就是使用類的時候已經將對象創建完畢(不管以后會不會使用到該實例化對象,先創建了再說。很着急的樣子,故又被稱為“餓漢模式”),常見的實現辦法就是直接new實例化。

public class Singleton {

    // 將自身實例化對象設置為一個屬性,並用static、final修飾
    private static final Singleton instance = new Singleton();
    
    // 構造方法私有化
    private Singleton() {}
    
    // 靜態方法返回該實例
    public static Singleton getInstance() {
        return instance;
    }
}

“餓漢模式”的優缺點:

優點:實現起來簡單,沒有多線程同步問題。

缺點:當類SingletonTest被加載的時候,會初始化static的instance,靜態變量被創建並分配內存空間,從這以后,這個static的instance對象便一直占着這段內存(即便你還沒有用到這個實例),當類被卸載時,靜態變量被摧毀,並釋放所占有的內存,因此在某些特定條件下會耗費內存。

 

實現二:延遲加載 / “懶漢模式”

延遲加載就是調用get()方法時實例才被創建(先不急着實例化出對象,等要用的時候才給你創建出來。不着急,故又稱為“懶漢模式”),常見的實現方法就是在get方法中進行new實例化。

public class Singleton {

    // 將自身實例化對象設置為一個屬性,並用static修飾
    private static Singleton instance;
    
    // 構造方法私有化
    private Singleton() {}
    
    // 靜態方法返回該實例
    public static Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

“懶漢模式”的優缺點:

優點:實現起來比較簡單,當類SingletonTest被加載的時候,靜態變量static的instance未被創建並分配內存空間,當getInstance方法第一次被調用時,初始化instance變量,並分配內存,因此在某些特定條件下會節約了內存。

缺點:在多線程環境中,這種實現方法是完全錯誤的,根本不能保證單例的狀態。

 

實現三:線程安全的“懶漢模式”

public class Singleton {

    // 將自身實例化對象設置為一個屬性,並用static修飾
    private static Singleton instance;
    
    // 構造方法私有化
    private Singleton() {}
    
    // 靜態方法返回該實例,加synchronized關鍵字實現同步
    public static synchronized Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

優點:在多線程情形下,保證了“懶漢模式”的線程安全。

缺點:眾所周知在多線程情形下,synchronized方法通常效率低,顯然這不是最佳的實現方案。

 

實現四:DCL雙檢查鎖機制(DCL:double checked locking)

public class Singleton {

    // 將自身實例化對象設置為一個屬性,並用static修飾
    private static Singleton instance;
    
    // 構造方法私有化
    private Singleton() {}
    
    // 靜態方法返回該實例
    public static Singleton getInstance() {
        // 第一次檢查instance是否被實例化出來,如果沒有進入if塊
        if(instance == null) {
            synchronized (Singleton.class) {
                // 某個線程取得了類鎖,實例化對象前第二次檢查instance是否已經被實例化出來,如果沒有,才最終實例出對象
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

方法四算是單例模式的最佳實現方式。內存占用率高,效率高,線程安全,多線程操作原子性。

 

參考
1、高洪岩,Java多線程編程核心技術,機械工業出版社

2、https://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM