SyncHashtable这个[Object key]不使用锁定

时间:2011-06-05 06:36:46

标签: c#-3.0 clr base-class-library

我完成了.Net框架BCL中定义的SyncHashtable的实现。

此类提供对多个读者和作者的同步访问。

其中一种方法实现为

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;
                }
            }
        }

由于 的Vivek

2 个答案:

答案 0 :(得分:2)

锁定Hashtable以进行读取是没有必要的,因为在这种情况下它已经是线程安全的。

Hashtable州的文档:

  

Hashtable是线程安全的,可供多个读者线程和单个写入线程使用。

通过锁定写访问,实际上只有一个编写器,因此不需要锁定读取。

请注意,虽然Hashtable适用,Dictionary<TKey, TValue>的情况

答案 1 :(得分:0)

不知道Hashtable的线程安全保证我认为你是正确的,因为lock关键字是监视器而不是隐式读写器锁。这肯定会造成不良影响。但是,考虑到今天的情况,我会查看.NET 3.5的Reactive Extensions,它附带了一个System.Threading程序集,它包含作为.NET 4.0一部分的新并发类。这些类更适合处理对集合的多线程访问。