C#锁定在锁定块中重新分配的对象

时间:2010-06-02 11:54:38

标签: c# multithreading locking

我在类中有这个代码:

private static MyObject _locker = new MyObject();

...

lock (_locker)
{
     ...
     _locker = new MyObject();
     ...
}

它会锁定_locker吗?

3 个答案:

答案 0 :(得分:7)

不,它不会。从C#规范(重点是我的):

  

lock (x) ...形式的锁定语句,其中x是a的表达式   参考类型,正是   相当于

System.Threading.Monitor.Enter(x);
try {
  ...
}
finally {
  System.Threading.Monitor.Exit(x);
}
     

,但x只评估一次

由于未重新评估x,因此将释放锁定。

答案 1 :(得分:2)

不要这样做。考虑完全使用单独的对象来保存锁的状态,而不一定是要在lock语句中保护的对象。我经常写这样的代码(好吧,不经常):

private static readonly object _locker = new object();
private static MyObject _object;
...

lock (_locker)
{
     ...
     _object = new MyObject();
     ...
}

它涉及的程序流程与您正在查看的完全不同。 lock()定义了代码中的一个关键部分 - 你不会将它用作任何类型对象的通用线程安全机制(我认为你的意图在你的代码中?)

答案 2 :(得分:2)

我认为它会在调用MyObject时保持_locker设置为lock的实例上的锁定,即它将保持_locker的原始实例上的锁定。 1}},而不是新创建的MyObject实例。在以下代码中,第一次调用MyObject("OriginalInstance")时,锁定将保留在lock上。当它第二次被调用时,它将锁定MyObject("NewInstance")

private static MyObject _locker = new MyObject("OriginalInstance");

...

lock (_locker)
{
    ...
    _locker = new MyObject("NewInstance");
    ...
}

因此,下一个线程可以毫无问题地进入临界区,因为新实例未被锁定。

无论如何,做这样的事情通常是被认为是不好的做法。有关如何使用lock的一些建议,请参阅MSDN