2012-10-24 40 views
3

使用雙重檢查鎖定是否正確使用非靜態字段?C檢查類成員的雙重檢查鎖定#

class Foo 
{ 
    private SomeType member; 
    private readonly object memeberSync = new object(); 
    public SomeType Memeber 
    { 
     get 
     { 
     if(member == null) 
     { 
      lock(memeberSync) 
      { 
       if(member == null) 
       { 
        member = new SomeType(); 
       } 
      } 
     } 
     return object; 
     } 
    } 
} 
+3

你真的*試圖實現單例模式嗎?如果是這樣,則有更清晰的模式。請參閱http://csharpindepth.com/Articles/General/Singleton.aspx –

回答

0

這是一個由某些人推薦的做法,因爲您的鎖可能不適用,直到另一個鎖被釋放。

在這種情況下,兩個線程同時訪問getter,第一個線程獲取鎖,第二個線程等待。

第一個完成後,第二個線程現在鎖定了。

在可能的情況下,您應該檢查在當前線程獲取鎖定之前變量是否已由另一個線程創建。

2

外部檢查會提高性能,一旦初始化member,每次訪問屬性時都不必獲取鎖。如果您經常從多個線程訪問該屬性,則鎖的性能下降可能非常明顯。

內部檢查對於防止競爭條件是必要的:沒有這種情況,兩個線程可能會處理外部if語句,然後兩者都會初始化member

嚴格地說,外if不是必要,但它被認爲是很好的做法,(在大量線程的應用程序)的性能優勢將是明顯的。

6

使用不帶靜態字段的雙重檢查鎖定是否正確?

是的,沒有錯,你的代碼中使用雙重檢查與lock得到線程安全延遲加載。如果你使用的是.NET 4,那麼建議使用Lazy類,這種方法與線程安全得到相同的結果延遲加載但它也使你的代碼更簡單,更具可讀性。

class Foo 
{ 
    private readonly Lazy<SomeType> _member = 
            new Lazy<SomeType>(() => new SomeType()); 

    public SomeType Member 
    { 
     get { return _member.Value; } 
    } 
}