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

我在一个类中有这个代码:

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

它会锁定_locker吗?

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

formslock (x) ...的锁定语句lock (x) ...其中x是引用类型的表达式,精确等效于

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

除了x只评估一次

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

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

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

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

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

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

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

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