单例模式是 C# 开发中最常用的设计模式之一。它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。
在 C# 应用程序中,单例模式通常用于管理共享资源,例如:
要实现一个标准的单例类,必须满足以下条件:
在 C# 中实现单例有多种方式,主要区别在于线程安全性和延迟加载 (Lazy Loading) 的处理。
这是最基本的实现,但在多线程环境下是不安全的。如果两个线程同时判断 `_instance == null`,可能会创建两个实例。
public class Singleton { private static Singleton _instance; // 私有构造函数 private Singleton() { } public static Singleton Instance { get { // 线程不安全! if (_instance == null) { _instance = new Singleton(); } return _instance; } } }
通过 `lock` 关键字确保同一时间只有一个线程执行创建实例的代码。
public class Singleton { private static Singleton _instance; private static readonly object _lock = new object(); private Singleton() { } public static Singleton Instance { get { // 每次访问都会加锁,性能较差 lock (_lock) { if (_instance == null) { _instance = new Singleton(); } return _instance; } } } }
这种方式既保证了线程安全,又避免了每次访问都加锁带来的性能损耗。只有在实例未创建时才加锁。
public class Singleton { private static Singleton _instance; private static readonly object _lock = new object(); private Singleton() { } public static Singleton Instance { get { // 第一次检查:如果已经创建,直接返回,避免加锁 if (_instance == null) { lock (_lock) { // 第二次检查:防止多个线程同时通过了第一次检查 if (_instance == null) { _instance = new Singleton(); } } } return _instance; } } }
利用 .NET CLR 的特性,静态构造函数只会执行一次。这种方式非常简单且线程安全,但缺点是不支持延迟加载(类一加载,实例就被创建,即使你还没用到它)。
public sealed class Singleton { // CLR 保证了静态字段初始化的线程安全性 private static readonly Singleton _instance = new Singleton(); // 显式静态构造函数告诉 C# 编译器不要将类型标记为 BeforeFieldInit static Singleton() { } private Singleton() { } public static Singleton Instance { get { return _instance; } } }
在 .NET 4.0 及更高版本中,这是最推荐的实现方式。它利用 `System.Lazy<T>` 类型自动处理线程安全和延迟加载,代码简洁且高效。
public sealed class Singleton { // Lazy<T> 默认是线程安全的 private static readonly Lazy<Singleton> _lazy = new Lazy<Singleton>(() => new Singleton()); private Singleton() { } public static Singleton Instance { get { return _lazy.Value; } } }
| 实现方式 | 线程安全 | 延迟加载 | 复杂度 | 推荐指数 |
|---|---|---|---|---|
| 简单实现 | No | Yes | 低 | 不推荐 |
| 简单加锁 | Yes | Yes | 中 | 一般 |
| 双重检查锁定 | Yes | Yes | 高 | 一般 |
| 静态初始化 | Yes | No | 低 | 推荐 (如果不需要延迟加载) |
| System.Lazy<T> | Yes | Yes | 低 | 强烈推荐 |