AI 摘要
文章详细介绍了单例设计模式,这是一种创建型模式,用于确保一个类只有一个实例,并提供全局访问点。文章讨论了实现单例模式的六个版本,包括懒汉式、饿汉式和使用.NET的Lazy<T>类型等方法,并考虑了线程安全性、延迟加载和性能问题。每种方法都有代码示例和简要说明,同时提供了相关参考资料链接。
定义
单例模式(Singleton Design Pattern)是一种创建型设计模式,它能够保证一个类只有一个实例,并提供一个访问该实例的全局节点。
三个必要条件:
- 构造函数必须是私有的,保证类的外部不能创建类的实例。
- 通过一个私有的静态变量来存储其唯一实例。
- 通过提供一个公开的静态方法,使得外部使用者可以访问类的唯一实例。
三个必要问题:
- 是否线程安全
- 是否延时加载
- 是否需要加锁(锁会导致低性能)
实现
版本一:懒汉式(不推荐)
线程安全 |
延迟加载 |
加锁 |
否 |
是 |
创建对象时未加锁,获取对象时未加锁 |
public sealed class Singleton
{
private static Singleton _instance = null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
版本二:懒汉式(一般推荐)
线程安全 |
延迟加载 |
加锁 |
是 |
是 |
创建对象时加锁,获取对象时加锁 |
public sealed class Singleton
{
private static Singleton _instance = null;
private static readonly object InstanceLock = new();
private Singleton()
{
}
public static Singleton Instance
{
get
{
lock (InstanceLock)
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
}
版本三:双重检测(不推荐,不如版本五)
线程安全 |
延迟加载 |
加锁 |
是 |
是 |
创建对象时加锁,获取对象时未加锁 |
public sealed class Singleton
{
private static Singleton _instance = null;
private static readonly object InstanceLock = new object();
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (InstanceLock)
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
}
版本四:饿汉式(推荐)
线程安全 |
延迟加载 |
加锁 |
是 |
否 |
创建对象时未加锁,获取对象时未加锁 |
public sealed class Singleton
{
private static Singleton instance = new Singleton();
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
版本五:躺平式-静态内部类(推荐)
线程安全 |
延迟加载 |
加锁 |
是 |
是 |
创建对象时未加锁,获取对象时未加锁 |
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton instance
{
get
{
return Nested.instance;
}
}
private class Nested
{
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
版本六:.NET4 的 Lazy<T> 类型(强烈推荐)
线程安全 |
延迟加载 |
加锁 |
是 |
是 |
创建对象时未加锁,获取对象时未加锁 |
public sealed class Singleton
{
private static readonly Lazy<Singleton> Lazy = new(() => new Singleton());
public static Singleton Instance => Lazy.Value;
private Singleton()
{
}
}
参考资料