SyncHashtable this[Object key] 不使用锁定

发布于 2024-11-13 07:14:40 字数 975 浏览 4 评论 0原文

我经历了 .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;
                }
            }
        }

谢谢 维韦克

I went through the implementation of SyncHashtable in defined in .Net framework BCL.

This class provides synchronized access to multiple readers and writers.

One of the methods is implemented as

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

In my opinion the get method should also have a lock on Syncroot before accessing the object.

Consider the scenario :

Thread 1 : Deleting keys from the Hashtable.

Thread 2 : Reading objects using keys.

If a context switch occurs in thread 2 while reading the object and if thread 1 deletes the object , then in such a case the read operation will fail or give inconsistent result.

Hence couldn't we implement this method like this

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

Thanks
Vivek

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三岁铭 2024-11-20 07:14:40

没有必要锁定用于读取的Hashtable,因为在这些情况下它已经是线程安全的。

Hashtable 的文档指出:

哈希表是线程安全的,可供多个读取线程和单个写入线程使用。

通过锁定写入访问,实际上只有一个写入者,因此无需锁定读取。

请注意,虽然对于 Hashtable 是这样,但对于 Dictionary 却不是这样。

Locking the Hashtable for reading is not necessary because that is already thread safe under these circumstances.

The documentation for Hashtable states:

Hashtable is thread safe for use by multiple reader threads and a single writing thread.

By locking the write access, there is in effect only a single writer, and it is therefore unnecessary to lock reads.

Note that while this is true for Hashtable, it is not the case for Dictionary<TKey, TValue>.

哆啦不做梦 2024-11-20 07:14:40

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

Not knowing the thread-safety guarantees of the Hashtable I believe you are correct as the lock keyword is a monitor not a implicit reader-writer lock. This could definitely cause undesirable effects. However, given the situation as of today I'd look to the Reactive Extensions for .NET 3.5, it ships with a System.Threading assembly that contains the new concurrent classes as part of the .NET 4.0. These classes are much better suited for dealing with multi-threaded access to collections.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文