如何在C#中使用多个变量来锁定范围
我有一种情况,即只有两个更衣室对象空闲时才应执行代码块。
我希望有类似的东西:
lock(a,b) { // this scope is in critical region }
然而,似乎没有那样的东西。 这是否意味着这样做的唯一方法是:
lock(a) { lock(b) { // this scope is in critical region } }
这甚至可以按预期工作吗? 虽然代码编译,但我不确定它是否会实现我所期望的。
我期待它,尽管有可能会导致死锁的情况。
通常,代码将尝试锁定a
然后继续锁定b
如果成功)。 这意味着如果它可以锁定a
和b
,它只会执行代码。 这是你想要的。
但是,如果某些其他代码已经锁定了b
则此代码将无法执行您所期望的操作。 您还需要确保在需要锁定a
和b
您尝试以相同的顺序获取锁定。 如果先获得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
。 否则你很容易发现自己陷入僵局。