單例模式的實現方式

一、單例模式的概念

單例模式是一種創建型模式,它保證一個類只能被實例化一次,並提供了一個訪問該實例的全局訪問點。單例模式可以用來解決資源統一分配的問題,如線程池、全局緩存等。

單例模式的標準實現包含三個要素:1.私有的構造函數,2.靜態變數實例,3.公共的訪問方法。而實現單例模式的方式有很多,接下來我們將討論這些實現方式。

二、單例模式的五種實現方式

下面是單例模式的五種實現方式:

餓漢式

public class Singleton {
    一個私有的、靜態的、final類型的實例對象
    private static final Singleton INSTANCE = new Singleton();
    
    私有構造函數
    private Singleton() {}
    
    公開訪問點
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

餓漢式單例模式在類載入時已經創建了實例對象,因此不存在線程安全問題,但是如果實例對象很大,會導致啟動時間變長。

懶漢式

public class Singleton {
    私有的實例對象
    private static Singleton instance = null;
    
    私有構造函數
    private Singleton() {}
    
    公開訪問點
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

懶漢式單例模式在第一次調用公開訪問點時才創建實例對象,解決了餓漢式單例模式啟動時間長的問題。但是在多線程環境下,存在線程安全問題,需要加鎖。

雙重檢查

public class Singleton {
    一個私有的、volatile類型的實例對象
    private static volatile Singleton instance = null;
    
    私有構造函數
    private Singleton() {}
    
    公開訪問點
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        } 
        return instance;
    }
}

雙重檢查單例模式在多線程環境下解決了線程安全問題,並且不需要每次都加鎖,相對於懶漢式單例模式有更優的性能。

靜態內部類

public class Singleton {
    私有構造函數
    private Singleton() {}
    
    私有靜態內部類
    private static class SingletonHolder {
        一個私有的、靜態的、final類型的實例對象
        private static final Singleton INSTANCE = new Singleton();
    }
    
    公開訪問點
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

靜態內部類單例模式在外部類被載入的時候並不會被初始化,只有在調用公開訪問點時才會初始化內部類,從而創建實例對象。這種方式既避免了餓漢式單例模式的啟動時間長的問題,又避免了懶漢式單例模式的線程安全問題。

枚舉

public enum Singleton {
    INSTANCE; 
    
    公開方法
    public void doSomething() {}
}

枚舉單例模式是餓漢式單例模式的升級版,它天生就是線程安全的,並且可以防止反序列化創建新的實例對象。其優點在於簡潔明了,不需要做額外的工作即可實現單例模式。

三、單例模式的幾種實現方式

除了上述五種實現方式之外,還有一些單例模式的實現方式:

延遲初始化佔位類

public class Singleton {
    私有變數
    private String data = "this is a lazy initialized singleton";
    
    私有構造函數
    private Singleton() {}
    
    私有靜態內部類
    private static class Holder {
        私有靜態變數
        private static final Singleton INSTANCE = new Singleton();
    }
    
    私有靜態初始化方法
    private static final Singleton getInstance() {
        return Holder.INSTANCE;
    }
    
    公開訪問點
    public String getData() {
        return data;
    }
}

延遲初始化佔位模式是一種比較新穎的單例實現方式,它通過聲明一個私有的靜態內部類,該內部類包含單例的實例對象,並在第一次調用公開訪問點時才初始化該實例對象,從而達到懶漢式單例模式的效果,並且不需要加鎖保證線程安全。

ThreadLocal

public class Singleton {
    一個私有的ThreadLocal類型的實例對象
    private static ThreadLocal instance = new ThreadLocal() {{
        initialValue = new Singleton();
    }};
    
    私有構造函數
    private Singleton() {}
    
    公開訪問點
    public static Singleton getInstance() {
        return instance.get();
    }
}

ThreadLocal單例模式是一種較為特殊的單例實現方式,它結合了懶漢式單例模式和多線程環境下線程安全的特性,並且在每個線程中都可以有自己獨立的實例對象,從而達到可重入的效果。

四、單例模式的6種實現方式

除了上述介紹的五種實現方式之外,還有一種單例模式的實現方式,來看看它的實現:

註冊式單例

public class Singleton {
    一個私有的靜態Map類型的實例對象
    private static Map registry = new ConcurrentHashMap();
    
    靜態代碼塊
    static {
        Singleton instance = new Singleton();
        registry.put(instance.getClass().getName(), instance);
    }
    
    protected Singleton() {}
    
    公共靜態方法,返回指定名稱的單例對象
    public static Singleton getInstance(String name) {
        if (name == null) {
            name = Singleton.class.getName();
        }
        if (registry.get(name) == null) {
            registry.put(name, new Singleton());
        }
        return registry.get(name);
    }
}

註冊式單例模式將每個實例對象都註冊到一個Map容器中,以便在需要時快速獲取。該實現方式相對於其他實現方式來說比較複雜,而且需要考慮線程安全問題。

五、7種方式實現單例模式

雖然單例模式的標準實現方式只有三個要素,但是在實際使用的時候,我們還可以按照以下的七種方式來實現單例模式:

枚舉

和上面的枚舉單例模式一樣,這裡就不再重複介紹了。

餓漢式

和上面的餓漢式單例模式一樣,這裡就不再重複介紹了。

懶漢式

和上面的懶漢式單例模式一樣,這裡就不再重複介紹了。

雙重檢查

和上面的雙重檢查單例模式一樣,這裡就不再重複介紹了。

靜態內部類

和上面的靜態內部類單例模式一樣,這裡就不再重複介紹了。

延遲初始化佔位類

和上面的延遲初始化佔位類單例模式一樣,這裡就不再重複介紹了。

ThreadLocal

和上面的ThreadLocal單例模式一樣,這裡就不再重複介紹了。

六、實現單例模式的類具有

實現單例模式的類具有以下特點:

1.只能被實例化一次;

2.提供一個訪問該實例的全局訪問點;

3.在多線程環境下保證線程安全;

4.防止反序列化時創建新的實例對象。

七、單例模式的實現

以上方式都是通過私有的構造函數、靜態變數以及公開訪問點來實現單例模式的。

八、單例模式代碼實現

下面是一個簡單的單例模式實現的示例代碼:

public class Singleton {
    一個私有的、靜態的、final類型的實例對象
    private static final Singleton INSTANCE = new Singleton();
    
    私有構造函數
    private Singleton() {}
    
    公開訪問點
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

九、總結

單例模式是一種重要的設計模式,它可以幫助我們解決資源統一分配的問題,並且提升了程序的可維護性和可測試性。在實際開發中,我們可以選擇適合自己的單例模式實現方式,並注意線程安全問題。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/240810.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:22
下一篇 2024-12-12 12:22

相關推薦

  • Python緩存圖片的處理方式

    本文將從多個方面詳細闡述Python緩存圖片的處理方式,包括緩存原理、緩存框架、緩存策略、緩存更新和緩存清除等方面。 一、緩存原理 緩存是一種提高應用程序性能的技術,在網路應用中流…

    編程 2025-04-29
  • 手機安全模式怎麼解除?

    安全模式是一種手機自身的保護模式,它會禁用第三方應用程序並使用僅限基本系統功能。但有時候,安全模式會使你無法使用手機上的一些重要功能。如果你想解除手機安全模式,可以嘗試以下方法: …

    編程 2025-04-28
  • Python在線編輯器的優勢與實現方式

    Python在線編輯器是Python語言愛好者的重要工具之一,它可以讓用戶方便快捷的在線編碼、調試和分享代碼,無需在本地安裝Python環境。本文將從多個方面對Python在線編輯…

    編程 2025-04-28
  • Java表單提交方式

    Java表單提交有兩種方式,分別是get和post。下面我們將從以下幾個方面詳細闡述這兩種方式。 一、get方式 1、什麼是get方式 在get方式下,表單的數據會以查詢字元串的形…

    編程 2025-04-27
  • Qt State Machine與狀態機模式

    本文將介紹Qt State Machine和狀態機模式在Qt中的實現。Qt提供了QStateMachine和QState兩個類,可以方便地實現狀態機模式,並且能有效地處理複雜的、多…

    編程 2025-04-27
  • 用Pythonic的方式編寫高效代碼

    Pythonic是一種編程哲學,它強調Python編程風格的簡單、清晰、優雅和明確。Python應該描述為一種語言而不是一種編程語言。Pythonic的編程方式不僅可以使我們在編碼…

    編程 2025-04-27
  • Java多版本支持實現方式

    本文將從以下幾個方面闡述如何實現Java多版本支持,並給出可行的代碼示例。 一、多版本Java環境概述 Java是一門跨平台的編程語言,但是在不同的應用場景下,可能需要使用不同版本…

    編程 2025-04-27
  • SpringBoot Get方式請求傳參用法介紹

    本文將從以下多個方面對SpringBoot Get方式請求傳參做詳細的闡述,包括URL傳參、路徑傳參、請求頭傳參、請求體傳參等,幫助讀者更加深入地了解Get請求方式下傳參的相關知識…

    編程 2025-04-27
  • Python獲取APP數據的多種方式

    如果您需要對APP進行分析、數據採集、監控或者自動化測試,那麼您一定需要獲取APP的數據。本文將會介紹一些Python獲取APP數據的方式。 一、使用ADB工具獲取APP數據 AD…

    編程 2025-04-27
  • 顯示C++設計模式

    本文將詳細介紹顯示C++設計模式的概念、類型、優點和代碼實現。 一、概念 C++設計模式是在軟體設計階段定義,用於處理常見問題的可重用解決方案。這些解決方案是經過測試和驗證的,並已…

    編程 2025-04-27

發表回復

登錄後才能評論