首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 單例模式全攻略:從懶漢到雙重檢查鎖定、靜態初始化與線程安全完整比較

     編輯:關於C#

基礎版:懶漢式(非線程安全)

public class Singleton
{
    private static Singleton instance;
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            if (instance == null) instance = new Singleton();
            return instance;
        }
    }
}

優點:延遲實例化、可在屬性中加入邏輯(如子類實例化)。
缺點:多線程下 if (instance == null) 可能同時通過,產生多個實例。

推薦版:靜態初始化(.NET 執行階段保證線程安全)


public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();
    private Singleton() { }
    public static Singleton Instance => instance;
}

特點:

  • readonly 確保僅在靜態建構函式或宣告時賦值一次。
  • CLR 保證類別建構函式()只執行一次,天然線程安全。
  • sealed 禁止繼承,避免破壞單例語意。
  • 首次存取任何靜態成員時才初始化,兼具延遲載入。

這是 .NET 中最推薦的寫法,簡潔高效。

進階版:雙重檢查鎖定(需延遲初始化且建構複雜時)


public sealed class Singleton
{
    private static volatile Singleton instance;
    private static readonly object syncRoot = new object();
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new Singleton();
                }
            }
            return instance;
        }
    }
}

關鍵細節:

  • volatile 防止指令重排序,確保其他執行緒看到完全初始化後的物件。
  • 鎖定 syncRoot 而非 typeof(Singleton),避免跨 AppDomain 死鎖風險。
  • 雙重 if 減少鎖定開銷,僅首次建立時進入關鍵區。

對比總結表

寫法線程安全延遲載入建構彈性推薦指數
懶漢式❌✅✅⭐
靜態初始化✅ (CLR)✅ (首次靜態存取)❌ (無法自訂建構邏輯)⭐⭐⭐⭐⭐
Double-Check Locking✅✅✅⭐⭐⭐⭐

實務建議

  1. 95% 情況直接用靜態初始化。
  2. 若建構函式需傳參、讀取設定檔或執行耗時 I/O,改用 Double-Check Locking 或 Lazy<T>(.NET 4.0+ 內建支援)。
  3. 避免在單例中持有大量狀態,違反單一職責原則;考慮改用依賴注入容器管理生命週期。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved