SyncRoot对象真的是线程安全的吗?

时间:2012-01-06 12:10:50

标签: c# multithreading thread-safety syncroot

我是SyncRoot概念的新手。据我所知,用于锁定的对象应该是私有的。

但是HashTable有一个公共属性SyncRoot,它只是私有SyncRoot对象的包装器。在枚举集合时锁定HashTable.SyncRootrecommended

似乎我们可能会失败,因为它不再是私人的死锁。它真的是线程安全吗?

如果我制作自己的私人锁定机制怎么办? private readonly object _syncObject;

哪一个更好,为什么?

2 个答案:

答案 0 :(得分:6)

不,这不是.NET 1.x方法的真正问题。该属性是公开的,因为它具有可公开访问。问题在于枚举集合。没有任何方法以线程安全的方式实现它,当你完成时开始枚举和解锁时没有自动锁定的机制。 IEnumerable没有Completed方法,也没有继承IDisposable。

因此,要允许代码安全枚举,您需要访问锁定对象。因此,您可以使用该对象的锁来包装foreach语句。因此公共SyncRoot属性。

然而,许多程序员陷入困境的最大熊陷阱是假设没有必要。购买Synchronized属性为所有情况下线程安全的集合返回线程安全包装的概念。事实并非如此。

答案 1 :(得分:5)

ICollection.SyncRoot仅适用于预先通用的集合。它基本上已经过时了。

由于您提到的原因,这在通用集合中被删除了 - 您应该使用自己的锁定机制来控制对具有您需要的属性的集合的访问(保持锁定私有,避免死锁......),而不是使用SyncRoot对象,然后假设您的代码是神奇的线程安全的。