懒惰的线程安全 Singleton(使用双重锁定)
在 .NET 的早期版本中,这种线程安全版本的单例是必需的,其中 static
初始化不保证是线程安全的。在框架的更现代版本中,通常首选静态初始化单例, 因为在以下模式中很容易出现实现错误。
public sealed class ThreadSafeSingleton
{
private static volatile ThreadSafeSingleton instance;
private static object lockObject = new Object();
private ThreadSafeSingleton()
{
}
public static ThreadSafeSingleton Instance
{
get
{
if (instance == null)
{
lock (lockObject)
{
if (instance == null)
{
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
}
}
请注意,if (instance == null)
检查完成两次:一次获取锁定之前,一次之后。即使没有第一次空检查,此实现仍然是线程安全的。但是,这意味着每次请求实例时都会获取锁,这会导致性能受损。添加第一个空检查,以便除非必要,否则不会获取锁定。第二次空检查确保只有第一个获取锁的线程才会创建实例。其他线程将找到要填充的实例并向前跳过。