锁定字段或局部变量?

Roy*_*mir 9 .net c# multithreading locking .net-4.0

在我从Marc 的回答中读到这个问题之后....

我有时会看到人们锁定局部变量.

这段代码坏了吗?

public void Do()
{
 object  o  = new Object();
 lock (o)
     {
      ...
     }
}
Run Code Online (Sandbox Code Playgroud)

我认为object o = new Object();应该在方法之外作为一个Field.

由于每个线程都获得了一个新实例o,因此会有多个锁.

我在这里错过了什么?在这种特定情况下,它不应该锁定字段吗?

Til*_*lak 8

我相信对象o = new Object(); 应该在方法之外作为Field.

由于每个线程都获得了一个新的o实例,因此会有多个锁.

这里有什么我想念的吗?因为我知道它应该锁定字段(在这种特定情况下).

你的理解是正确的.代码被破坏.在这个实现中,即使lock处于活动状态,它也不会提供同步,因为它将在不同的对象上.

来自MSDN-lock c#

通常,避免锁定公共类型或超出代码控制范围的实例.常见的构造锁(this),lock(typeof(MyType))和lock("myLock")违反了这个指南:

  • 如果可以公开访问实例,则锁定(this)是一个问题.
  • 如果MyType可公开访问,则lock(typeof(MyType))是一个问题.
  • lock("myLock")是一个问题,因为进程中的任何其他代码使用相同的字符串,将共享相同的锁.

最佳做法是定义要锁定的私有对象,或私有静态对象变量以保护所有实例共有的数据.


Mic*_*erg 5

是.它被打破.

您希望将静态只读对象作为要锁定的私有字段.正如您所怀疑的那样,每次调用Do时,您的示例代码都会创建一个新对象,因此锁定将无法保留,并且根本无法工作.

private static object syncRoot = new object();

lock (syncRoot) { }
Run Code Online (Sandbox Code Playgroud)

  • 同意.它不必是静态的.取决于你在保护什么. (3认同)