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

本文关键字:安全 线程 对象 真的 SyncRoot | 更新日期: 2023-09-27 18:19:32

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

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

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

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

哪一个更好,为什么?

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

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

因此,为了允许代码安全地枚举,需要访问锁对象。因此,您可以在foreach语句中对该对象进行锁定。因此是公共SyncRoot属性。

然而,许多程序员陷入的最大陷阱是认为这没有必要。接受Synchronized属性为集合返回线程安全包装的概念,该包装在所有情况下都是线程安全的。事实并非如此。

ICollection.SyncRoot仅在预泛型集合上。它基本上已经过时了。

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