[英]Why this realization of Singleton Pattern can have two instances
我正在学习Singleton模式。 在msdn上,单例模式的第一个实现是:
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
public void Display()
{
Console.WriteLine("This is from Singleton!");
}
}
但是,此实现的主要缺点是它对多线程环境不安全。 如果单独的执行线程同时输入Instance属性方法,则可能会创建Singleton对象的一个以上实例。
我试图创建该类的两个实例:
Console.WriteLine("First Instance!");
Singleton s = Singleton.Instance;
s.Display();
Console.WriteLine("Second Instance!");
Singleton ss = Singleton.Instance;
ss.Display();
Console.ReadLine();
都创建了“ s”和“ ss”,所以我想我误会了一些东西。 您能否让我知道为什么要创建两个实例?
在这种情况下,您不会创建两个实例。 而是创建两个指向同一实例的变量。 第一次调用Singleton s = Singleton.Instance;
创建实例。 第二个调用只返回相同的实例。 如果为单例类提供另一个字段(将其称为字符串文本),然后调用s.text = "a";
ss.text
也将具有值“ a”;
为了使整个线程安全,您可以看一下Mutex类。
在代码段中,仅当始终由单线程访问模块时, if(instance == null)
检查才可以创建类的单个实例。
但是在多线程环境下,它将失败并导致Singleton类的多个实例。
假设T1和T2是两个线程,它们正在同时访问get方法。
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
解释如下:
if(instance == null)
,如果实例尚未初始化,则进入if块内部。 if(instance == null)
行,就在T1进入块时(T1尚未执行instance = new Singleton()
) if
阻塞,两个线程都将被允许进入。 Singleton
类实例。 在这里使用多个线程的正确方法如下:
get
{
if (instance == null)
{
lock();
if (instance == null)
{
instance = new Singleton();
}
unlock();
}
return instance;
}
两个(甚至更多个)单独的线程可以同时进行if (instance == null)
检查。 如果实例尚不存在,则两个检查都将返回true
。 然后,两个线程将走得更远,每个线程将创建自己的类实例。
解决方案: 双重检查锁定
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.