c#锁定问题:锁定(此)vs锁定(SyncRoot)

时间:2011-06-28 17:04:01

标签: c# locking

我有一个带有类型集合字段的类。

问题:

  1. 如果我lock(this),我是否也有效锁定了该集合?
  2. 什么更有效率,lock(this)或创建SyncRoot对象并执行lock(SyncRoot)

5 个答案:

答案 0 :(得分:12)

lock上不要this。可能是其他人也将该实例用作lock对象。使用专门指定的lock个对象。

  

1)如果我锁定(这个),我是否也有效地锁定了该集合?

没有

  

2)更有效率,锁定(this)或创建SyncRoot对象并锁定(SyncRoot)?

高效? 专注于语义。 lock this是危险的。不要这样做。性能差异(如果有的话)并不重要。

说真的,这类似于询问,什么会让我更快到达目的地,在高速公路上以错误的方式行驶100英里/小时,还是走路?

答案 1 :(得分:8)

始终使用lock(_syncRoot)

其中_syncRoot是私有字段(只需要是对象)。

这在效率方面没有区别,但你最好拥有一个你可以控制的私人领域来锁定。如果你锁定this,另一个对象也可能锁定它。

有关更好的解释,请参阅Why is lock(this) {...} bad?。另请查看锁定msdn article

通过锁定集合,您没有做任何事情来阻止它被更改。你可能有一个误解,就是锁没有做任何特别的事情来阻止那个对象被改变,它只有在每个关键代码都调用锁时才有效。

答案 2 :(得分:3)

当使用lock时,你没有对你放入锁内的物体做任何神奇的事情 - 它不会使它只读或类似的东西。它只是注意某些东西有一个锁定引用该对象。因此,如果有其他人试图同时锁定那个对象,它会按预期执行(阻止同步访问)。

lock不做的是关心您锁定的对象中的任何属性,字段或其他任何内容。所以不,你根本没有锁定集合。

在这个问题中对此进行了更详细的解释:Why is lock(this) {...} bad?(我从其他答案得到的但是答案非常好,我觉得它也应该包含在这里)。

至于效率,我不希望两者之间存在很大的性能差异。然而,正如其他人所说,你不应该锁定可能被你无法控制的东西锁定的东西。这就是为什么你会发现为此创建私有变量的原因。

就我个人而言,我给它一个比synclock更具描述性的名称来描述锁定过程的确切内容(例如saveLock)。

答案 3 :(得分:2)

很多人都说lock(this)很危险。但是The MSDN description of ICollection.SyncRoot声明:

  

对于底层商店不公开的集合,预期的实现是返回当前实例

如果某个班级遵循此指南,那么是,lock(this)实际上与lock(SyncRoot)相同。但是你不应该依赖这样的实现细节,而应该使用更明确的lock(SyncRoot)

当然,如果您不想公开公开锁定语义,但在类实现中使用锁定,那么您应该像其他人推荐的那样锁定私有对象,并且如MSDN所建议的那样。但这似乎不是你所要求的。

锁定实例(lock(this))和锁定公共属性(lock(SyncRoot))都会使您无法控制代码锁定。如果您打算向调用者公开锁定语义,那么您别无选择。

答案 4 :(得分:1)

始终锁定锁定代码控制的内容。您无法控制类型的类型或实例。