單例模式(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 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>。本文從基礎結構、線程安全實現到實戰日誌案例完整演示,助您避開併發陷阱,正確落地單例模式。