2013-10-30 23 views
6

我們在工作中討論了鎖定和發生了什麼。觸發此討論的代碼是:使用鎖的含義是什麼(typeof(string))

 string name = (string)context.Cache[key]; 

     if (String.IsNullOrEmpty(name)){ 

      lock (typeof(string)){ 
       name = (string)context.Cache[key]; 
       //.. other code to get the name and then store in the cache 
      } 
     } 

我認爲這是直接的:尋找在高速緩存中的值,如果它不存在,然後得到一個鎖,從而沒有其他中斷而代碼獲取名字並將其存儲在緩存中。

我們的討論重點是(typeof(string))是否是最好的做事方式,究竟是做什麼。

我的問題是lock(typeof(string))到底做了什麼?它創建一個本地字符串來使用鎖嗎?它創建的東西是否具有更廣的範圍,因此可能不安全。

MSDN lock statement

+2

不,它鎖定整個類型 - [它可能是危險的](http://stackoverflow.com/questions/1603008/why-is-lock-typeof-mytype-a-problem)。如果它只是創建了一個隨機字符串來鎖定,其他鎖如何知道鎖定該字符串的同一個實例?我建議你製作一個虛擬對象來鎖定,就像'private object _lockOnThis = new object()'一樣。 – vcsjones

+0

我認爲typeof(SomeType)將始終返回相同類型的相同Type實例。所以你會使用一個全球可用的實例作爲鎖,這不是最好的想法恕我直言。 – helb

+0

@vcsjones我目前正在移除這種鎖定方式的所有實例,但對它做了什麼感興趣。 –

回答

2

如果鎖定在Type這將意味着你具有基於Type的該實例相互排斥的訪問。其含義是在執行此操作的應用程序中的兩個線程將無意中阻塞彼此或導致無法預料的死鎖。

請記住,typeof(someType)只是返回一個Type實例。

將對象專用於鎖定複雜流程(如在課堂中聲明readonly object)通常是最佳做法。如果鎖只需要訪問一個私有變量,比如一個集合,那麼鎖定該集合就相當好。

+0

這是我們最終在討論中達成的結論。 –

+0

我不確定是接受Jon Skeet的回答還是Michael的回答,因爲兩者都是很好的答案。邁克得到更少的分數,以便擺動它。 –

1

當你鏈接到網頁上顯示:

一般情況下,避免鎖定在一個公共類型,或者超出你的代碼的控制情況。公共構造鎖(this),鎖(typeof(MyType))和鎖(「myLock」)違反此準則:

lock (typeof (MyType))如果MyType可公開訪問,則會出現問題。

8

我的問題是lock(typeof(string))究竟做了什麼?

它鎖定在Type對象引用typeof運算符返回引用。

這意味着任何代碼做同樣的事情在同一進程內的任何地方(或者至少相同的應用程序域)將共享相同的鎖。聽起來對我來說是個壞主意。

我會建議你創建一個對象只是鎖定於:

private static readonly object CacheLock = new object(); 

... 

lock (CacheLock) 
{ 
    ... 
} 

這樣,你可以很容易地看到發生了什麼事情來鎖定該對象上。

+0

鎖定專用對象的好處是否會超過鎖定主體共享資源?假設這個緩存只是一個與你的CacheLock相同的對象。 –

+0

@ MichaelJ.Gray:這意味着您可以輕鬆地檢查該對象上的鎖定。你知道.NET中的任何代碼本身是否鎖定緩存嗎?我不。 –

+0

我想我對你的評論有點困惑。如何更容易檢查是否鎖定了「CacheLock」而不是您要訪問的緩存(不是typeof(Cache),請注意您)?如果我有一個'lock(this.cache){..}'這應該是更正確的,我相信。我不確定爲什麼這種趨勢已經開始,像針對單個對象使用'lock(this.cacheLocker){..}'這樣的東西;我可以理解用於複雜進程的'cacheLocker',其中類型在內部是線程安全的並公開線程安全方法。 –

相關問題