为什么要锁定 Collection.SyncRoot 而不是仅仅锁定集合?

发布于 2024-11-17 21:42:03 字数 224 浏览 5 评论 0原文

我试图理解 ICollection 中同步根的意义。为什么不直接锁定集合呢?

lock(myCollection)
{
    //do stuff to myCollection
}

lock(myCollection.SyncRoot)
{
    //do stuff to myCollection
}

I'm trying to understand the point of the syncroot in ICollection. Why not just lock the collection?

lock(myCollection)
{
    //do stuff to myCollection
}

vs

lock(myCollection.SyncRoot)
{
    //do stuff to myCollection
}

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

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

发布评论

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

评论(2

喵星人汪星人 2024-11-24 21:42:03

通常,如果线程安全是一个严重问题,我会避免使用这些选项。

更好的选择通常是维护您自己的私有变量,并在需要的所有方法中锁定它 - 包括访问集合的整个公共 API。

真正的危险在于,通过锁定暴露或可能暴露给外部世界的类型,您可能会打开“外部世界”扰乱同步的能力。如果使用多个锁,这可能会导致死锁(如果外部锁在您不期望的东西上)。

通过创建私有变量并专门锁定它,您就可以“控制”情况。这使得正在发生的事情变得更加清楚。此外,它还简化了多个对象之间的同步,尤其是在您维护代码时,因为锁非常清晰。

Typically, if thread safety is a serious concern, I would avoid either of these options.

A far better option is typically to maintain your own private variable, and lock on it in all methods where it's required - including the entire public API that accesses the collection.

The real danger is that, by locking on a type that's exposed or could be exposed to the outside world, you potentially open up the ability for the "outside world" to mess with your synchronization. If more than one lock is being used, this can lead to dead locks (if the outside locks on something you aren't expecting).

By creating a private variable, and locking exclusively on it, you're "taking control" of the situation. This makes it much more clear what is occurring. In addition, it eases synchronization between multiple objects, especially later as you maintain the code, since the lock is very clear.

心如荒岛 2024-11-24 21:42:03

永远不要锁定 SyncRoot,因为我相信它会锁定整个集合。 如果要锁定,则应该创建一个对象并锁定它。例如

public class MyClass
{
   get {return lock(_lockObject) _myCollection ; }
   set {lock(_lockObject) _myCollection.Add(value); }


   private List<string> _myCollection = new List<string>();
   private object _lockObject = new object();
}

为了更好地阐明,
lock(myCollection.SyncRoot) 和 lock(myCollection) 做同样的事情。
因为 SyncRoot 属性看起来像这样

get { return this; }

Never lock on SyncRoot because I believe it does a lock(this) which is locking on the entire collection. If you're going to lock, you should create an object and lock on it. For example

public class MyClass
{
   get {return lock(_lockObject) _myCollection ; }
   set {lock(_lockObject) _myCollection.Add(value); }


   private List<string> _myCollection = new List<string>();
   private object _lockObject = new object();
}

To better clarify,
lock(myCollection.SyncRoot) and lock(myCollection) do the same thing.
Because the property SyncRoot looks something like this

get { return this; }

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