2017-04-16 160 views
0

我想知道在多線程情況下單例如何工作。 假設2個線程輸入實例化代碼,如下面的代碼所示,第1個線程輸入實例化代碼,它鎖定該部分並繼續其操作,直到另一個線程等待。 因此,一旦第一個線程完成其操作,第二個線程將進入實例化代碼,現在我想知道誰承擔釋放鎖的責任,因爲第一個線程已完成其操作,第二個線程將創建新實例或將共享第一個線程實例???單線程C多線程#

代碼:

public sealed class Singleton 
{ 
    private static Singleton instance = null; 
    // adding locking object 
    private static readonly object syncRoot = new object(); 
    private Singleton() { } 

    public static Singleton Instance 
    { 
     get 
     { 
      if (instance == null) 
      { 
       lock (syncRoot) 
       { 
        if (instance == null) 
        { 
         instance = new Singleton(); 
        } 
       } 
      } 
      return instance; 
     } 
    } 
} 
+1

[線程安全的C#Singleton模式(HTTP的可能重複://計算器。com/questions/12316406/thread-safe-c-sharp-singleton-pattern) – Sanket

+0

如果適用,請考慮使用依賴注入而不是單例。一個容器實例化所有應該有單個對象的類,並通過ctor將它們注入需要它們的類。 Unity是一個在C#中支持這個框架的框架。# – Itsik

回答

0

您在這裏使用了什麼叫雙重檢查鎖定,對於多線程代碼一個相當普遍的系列化格局。有用。

鎖,一旦你掉出lock範圍被自動釋放。

假設存在爭用,一個線程會測試 - >獲取 - >測試 - >初始化 - >釋放,然後下一個測試 - >獲取 - >測試 - >釋放:沒有雙重初始化。

0

一旦第一個線程完成其操作第二個線程將進入實例代碼,現在我想知道誰需要負責釋放鎖,因爲第一個線程已經完成了它的操作

每個線程獲取並單獨釋放鎖。第一個線程獲取鎖定;當它有鎖時,第二個線程不能獲取它。

一旦第一個線程釋放了鎖(當執行離開由lock語句控制的代碼塊時發生),第二個線程就可以獲取鎖並執行代碼。當它完成後,它會再次釋放鎖。

…並將第二個線程創建新的實例或將它共享第一個線程實例化?

在這個特定的實現中,即使第二個線程最初觀察到後臺字段爲null,該單例也只初始化一次。通過使用lock,代碼確保只有一個線程會實際創建單例實例。

有些情況下,可能會出現不止一個初始化的變化,但恕我直言,這些低劣的方式來做到這一點。

這就是說,對於這個問題,這是我的看法是,在.NET的背景下,即使是雙鎖上面不必要的複雜。在大多數情況下,使用簡單的字段初始值設定項即可。如果效率不夠高,可以使用Lazy<T>類。

一個更加深入的討論,請參閱提供有相關的堆棧溢出問題Thread Safe C# Singleton Pattern和引用。

+0

謝謝彼得!!!!!! – Pushkar

1

還有一個最好的方式來實現這一點,我們可以創建一個靜態構造函數這將是很好。