C# 单例模式
单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式常用于需要全局唯一对象的场景,比如配置文件管理、日志记录、数据库连接池等。
单例模式的核心特点
- 私有构造函数:防止外部通过 new 关键字创建实例。
- 静态实例:通过静态变量保存唯一的实例。
- 全局访问点:提供一个静态方法或属性,用于获取单例实例。
单例模式的实现方式
1. 最简单的单例模式(非线程安全)
public class Singleton
{// 静态变量保存唯一实例private static Singleton _instance;// 私有构造函数,防止外部实例化private Singleton() { }// 全局访问点public static Singleton Instance{get{if (_instance == null){_instance = new Singleton();}return _instance;}}
}
使用方式:
Singleton instance = Singleton.Instance;
缺点:多线程环境下可能会创建多个实例,不推荐在生产环境中使用。
2. 线程安全的单例模式(双重检查锁定)
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;}}
}
使用方式:
Singleton instance = Singleton.Instance;
优点:线程安全,适用于多线程环境。
3. 使用 Lazy<T>
实现单例模式(推荐)
Lazy<T>
是 .NET 提供的一种延迟初始化方式,默认是线程安全的。
public class Singleton
{private static readonly Lazy<Singleton> _lazyInstance = new Lazy<Singleton>(() => new Singleton());private Singleton() { }public static Singleton Instance{get{return _lazyInstance.Value;}}
}
使用方式:
Singleton instance = Singleton.Instance;
优点:简洁、线程安全,推荐使用。
4. 使用静态构造函数实现单例模式
静态构造函数在类第一次被访问时自动调用,且只会执行一次。
public class Singleton
{private static readonly Singleton _instance = new Singleton();// 静态构造函数确保线程安全static Singleton() { }private Singleton() { }public static Singleton Instance{get{return _instance;}}
}
使用方式:
Singleton instance = Singleton.Instance;
优点:简单且线程安全。
单例模式的使用场景
-
配置文件管理:全局只需要一个配置文件对象。
-
日志记录:全局只需要一个日志记录器。
-
数据库连接池:全局只需要一个连接池实例。
-
缓存管理:全局只需要一个缓存管理器。
注意事项
-
线程安全:在多线程环境下,必须确保单例模式的实现是线程安全的。
-
延迟初始化:如果单例对象的创建成本较高,可以使用延迟初始化(如
Lazy<T>
)。 -
避免滥用:单例模式是全局状态,滥用可能导致代码难以测试和维护。
总结
-
最简单的单例模式:适用于单线程环境。
-
双重检查锁定:适用于多线程环境。
-
Lazy<T>:推荐使用,简洁且线程安全。
-
静态构造函数:简单且线程安全。
根据具体需求选择合适的实现方式,推荐使用 Lazy<T>
或静态构造函数实现单例模式。