如何在C#中使用多个变量来锁定范围

我有一种情况,即只有两个更衣室对象空闲时才应执行代码块。

我希望有类似的东西:

lock(a,b) { // this scope is in critical region } 

然而,似乎没有那样的东西。 这是否意味着这样做的唯一方法是:

 lock(a) { lock(b) { // this scope is in critical region } } 

这甚至可以按预期工作吗? 虽然代码编译,但我不确定它是否会实现我所期望的。

我期待它,尽管有可能会导致死锁的情况。

通常,代码将尝试锁定a然后继续锁定b如果成功)。 这意味着如果它可以锁定ab ,它只会执行代码。 这是你想要的。

但是,如果某些其他代码已经锁定了b则此代码将无法执行您所期望的操作。 您还需要确保在需要锁定ab您尝试以相同的顺序获取锁定。 如果先获得b然后再获得b ,则会导致死锁。

 lock(a) lock(b) { // this scope is in critical region } 

这可能会阻塞,直到线程可以获取a的锁。 然后,在获得该锁的情况下,它将阻塞,直到线程可以获取b的锁。 所以这可以按预期工作。

但是,您必须小心不要在其他地方执行此操作:

 lock(b) lock(a) { // this scope is in critical region } 

这可能导致死锁情况,其中线程1已获取a的锁并且正在等待获取b的锁,并且线程2已获取b的锁并且正等待获取a的锁。

请求锁定两者应该工作正常。 lock(a)将阻止直到a空闲。 一旦你有了锁, lock(b)就会阻塞,直到你有b 。 之后,你有两个。

在这里你需要非常小心的一件事是订单。 如果您要这样做,请确保在锁定b之前始终锁定b 。 否则你很容易发现自己陷入僵局。