2011-06-05 64 views
2

我經歷了在.Net框架BCL中定義的SyncHashtable的實現。SyncHashtable this [對象鍵]不使用鎖定

此課程提供對多個讀者和作者的同步訪問。

其中一種方法被實現爲

public override Object this[Object key] { 
      get { 
        return _table[key]; 
      } 
      set { 
       lock(_table.SyncRoot) { 
        _table[key] = value; 
       } 
      } 
     } 

在我看來GET方法還應該訪問對象之前對SyncRoot上的鎖。

考慮場景:

線程1:從Hashtable刪除鍵。

線程2:使用鍵讀取對象。

如果在讀取對象時線程2發生上下文切換,並且線程1刪除了該對象,則在這種情況下,讀取操作將失敗或導致不一致的結果。

因此,我們不能把實現這樣

public override Object this[Object key] { 
      get { 
       lock(_table.SyncRoot) 
        { 
        return _table[key]; 
        } 
      } 
      set { 
       lock(_table.SyncRoot) { 
        _table[key] = value; 
       } 
      } 
     } 

由於這種方法 維韋克

回答

2

Hashtable鎖定爲閱讀不是必要的,因爲在這種情況下,它已經是線程安全的。

Hashtable狀態的文檔:

Hashtable是線程安全的被多個讀線程和一個寫線程使用。

通過鎖定寫訪問,實際上只有一個寫入器,因此不必鎖定讀取。

請注意,雖然這是Hashtable,但它是而不是的情況下爲Dictionary<TKey, TValue>

+0

我沒有調用Hashtable線程安全;我重複了文檔,因爲它對於特定場景(多個讀者和一個作者)是線程安全的。這反過來使得SyncHashtable線程安全無需鎖定讀取。 – Sven 2011-06-05 07:59:37

+0

我只是想用不同的方式來表達,現在我認爲這可能是沒有必要的。我刪除了原來的評論。 – 2011-06-05 08:04:59

0

不知道Hashtable我相信你是正確的線程安全保證爲鎖定關鍵字是一個監視器不是一個隱含的讀寫器鎖。這肯定會造成不良影響。然而,考慮到今天的情況,我會看看.NET 3.5的Reactive Extensions,它附帶了一個System.Threading程序集,它包含作爲.NET 4.0一部分的新併發類。這些類更適合處理對集合的多線程訪問。

+0

正如我在我的回答中所說的,Hashtable對多個讀者和一個作者是線程安全的,所以沒有必要鎖定。 但是,如果可能的話,我會同意你的建議來使用ConcurrentDictionary 。 – Sven 2011-06-05 07:54:39