我在类中有这个代码:
private static MyObject _locker = new MyObject();
...
lock (_locker)
{
...
_locker = new MyObject();
...
}
它会锁定_locker吗?
答案 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。