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

.NET 設計模式實戰:單例模式線程安全實現與最佳實踐

     編輯:關於.NET

單例模式核心定義

單例模式(Singleton Pattern)確保一個類別僅有一個實例,並提供全域存取點。核心要素:私有建構子、靜態私有實例變數、公開靜態獲取方法。

經典結構圖

單例模式結構圖

線程安全的雙重檢查鎖定實現

public class Singleton
{
    private static Singleton instance;
    private static readonly object _lock = new object();

    private Singleton() { }

    public static Singleton GetInstance()
    {
        if (instance == null) // 第一次檢查,避免不必要鎖定
        {
            lock (_lock)
            {
                if (instance == null) // 第二次檢查,確保單一實例
                {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

客戶端驗證

static void Main(string[] args)
{
    Singleton singleton1 = Singleton.GetInstance();
    Singleton singleton2 = Singleton.GetInstance();
    if (singleton1 == singleton2)
    {
        Console.WriteLine("實例 singleton1 與 singleton2 相同!");
    }
    Console.ReadKey();
}

運行結果

實戰案例:郵件日誌記錄器

場景:多線程環境下寫入郵件發送日誌至文件,需確保同一時間僅一個實例操作文件,避免併發衝突。

郵件日誌結構

完整實現

public class EmailLog
{
    private static object _lock = new object();
    private static EmailLog _instance;
    private static object _fileLock = new object();

    private EmailLog() { }

    public static EmailLog GetInstance()
    {
        lock (_lock)
        {
            if (_instance == null)
            {
                _instance = new EmailLog();
            }
        }
        return _instance;
    }

    public void WriteEmailLog(string message)
    {
        string filePath = System.AppDomain.CurrentDomain.BaseDirectory + "mail.txt";
        StreamWriter sw = null;
        FileStream fs = null;
        lock (_fileLock)
        {
            if (!File.Exists(filePath))
            {
                fs = System.IO.File.Create(filePath);
                sw = new StreamWriter(fs, Encoding.UTF8);
            }
            else
            {
                fs = new FileStream(filePath, FileMode.Append);
                sw = new StreamWriter(fs, Encoding.UTF8);
            }
            sw.WriteLine("--------------------------------------------------------------------------");
            sw.WriteLine(message);
            sw.Flush();
            sw.Close();
        }
    }
}

客戶端調用

static void Main(string[] args)
{
    EmailLog w1 = EmailLog.GetInstance();
    w1.WriteEmailLog("發送Mail給靈動生活...");
    EmailLog w2 = EmailLog.GetInstance();
    w2.WriteEmailLog("發送Mail給James Hao...");
}

日誌輸出結果

進階補充:.NET 現代寫法

.NET 4.0+ 推薦使用 Lazy<T> 實現線程安全單例,碼更簡潔:

public sealed class Singleton
{
    private static readonly Lazy _instance = 
        new Lazy(() => new Singleton());
    
    public static Singleton Instance => _instance.Value;
    private Singleton() { }
}

總結

單例模式雖簡單,但線程安全實現需謹慎。雙重檢查鎖定是經典解法,現代 .NET 建議用 Lazy<T>。本文從基礎結構、線程安全實現到實戰日誌案例完整演示,助您避開併發陷阱,正確落地單例模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved