锁定字段或局部变量?

时间:2013-01-07 09:37:05

标签: c# .net multithreading .net-4.0 locking

在我从Marc阅读this an answer问题之后......

我有时会看到人们锁定本地变量。

这段代码坏了吗?

public void Do()
{
 object  o  = new Object();
 lock (o)
     {
      ...
     }
}

我认为object o = new Object();应该方法之外<{1}}。

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

我在这里缺少什么?在这种特殊情况下,它不应该锁定字段吗?

5 个答案:

答案 0 :(得分:8)

  

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

     

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

     

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

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

来自MSDN-lock c#

  

通常,避免锁定公共类型或超出代码控制范围的实例。常见的构造锁(this),lock(typeof(MyType))和lock(“myLock”)违反了这条准则:

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

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

答案 1 :(得分:5)

是。它被打破。

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

private static object syncRoot = new object();

lock (syncRoot) { }

答案 2 :(得分:2)

每次调用方法时都在创建o对象。所以,锁定不起作用。我的意思是其他线程不会等待锁无法发出信号并抢夺对此锁控制的资源的控制权。通常,锁对象是类中的私有变量,因此所有方法都会查看同一个对象。

答案 3 :(得分:2)

我个人认为没有任何理由使用此功能,因为lock只是将o实例中的特殊字段设置为信号状态。所以其他线程可以检查该实例的状态,并根据它执行lock语句中的代码或等待它的释放。

每次都有局部变量会分配一个新实例,因此对于每个线程都可以。

这看不出任何意义。

答案 4 :(得分:1)

锁定局部变量,锁定赢了。锁定全局变量可以使多个线程同步生效。

CURL_RETURNTRANSFER