为什么要锁定 Collection.SyncRoot 而不是仅仅锁定集合?
我试图理解 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常,如果线程安全是一个严重问题,我会避免使用这些选项。
更好的选择通常是维护您自己的私有变量,并在需要的所有方法中锁定它 - 包括访问集合的整个公共 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.
永远不要锁定 SyncRoot,因为我相信它会锁定整个集合。如果要锁定,则应该创建一个对象并锁定它。例如为了更好地阐明,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 exampleTo better clarify,lock(myCollection.SyncRoot) and lock(myCollection) do the same thing.
Because the property SyncRoot looks something like this
get { return this; }