[英]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.