我是 SyncRoot 概念的新手。据我所知,用于锁定的对象应该是私有的。
但是HashTable
有一个公共属性 ,SyncRoot
它只是私有 SyncRoot 对象的包装器。建议您HashTable.SyncRoot
在枚举集合时锁定。
看起来我们可能会因为死锁而失败,因为它不再是私有的。它真的是线程安全的吗?
如果我制作自己的私有锁定机制怎么办?
private readonly object _syncObject;
哪个更好,为什么?
我是 SyncRoot 概念的新手。据我所知,用于锁定的对象应该是私有的。
但是HashTable
有一个公共属性 ,SyncRoot
它只是私有 SyncRoot 对象的包装器。建议您HashTable.SyncRoot
在枚举集合时锁定。
看起来我们可能会因为死锁而失败,因为它不再是私有的。它真的是线程安全的吗?
如果我制作自己的私有锁定机制怎么办?
private readonly object _syncObject;
哪个更好,为什么?
不,这不是 .NET 1.x 方法的真正问题。该财产是公开的,因为它必须是公开的。问题在于枚举集合。没有任何方法可以以线程安全的方式实现它,没有机制可以在您开始枚举时自动锁定并在完成后解锁。IEnumerable 没有 Completed 方法,也没有继承 IDisposable。
所以为了让代码安全地枚举,你需要访问锁对象。因此,您可以使用对该对象的锁定来包装 foreach 语句。因此,公共 SyncRoot 属性。
然而,许多程序员陷入的最大陷阱是假设没有必要。接受 Synchronized 属性为在所有情况下都是线程安全的集合返回线程安全包装器的概念。它不是。
ICollection.SyncRoot
仅在前通用集合上。它基本上已经过时了。
由于您提到的原因,这已在通用集合中删除 - 您应该使用自己的锁定机制来控制对具有所需属性的集合的访问(保持锁定私有,避免死锁......),而不是使用 SyncRoot对象,然后假设您的代码是神奇的线程安全的。