为什么此代码不会导致僵局?
private static readonly object a = new object();
...
lock(a)
{
lock(a)
{
....
}
}
为什么是,也就是(为什么这是一个好主意)考虑以下情况,在a-> b:
void f()
{
lock(a)
{ /* do stuff inside a */ }
}
void doStuff()
{
lock(b)
{
//do stuff inside b, that involves leaving b in an inconsistent state
f();
//do more stuff inside b so that its consistent again
}
}
,我们只是违反了我们的锁定命令,并在我们的手上有潜在的僵局。
我们真的需要能够执行以下操作:
function doStuff()
{
lock(a)
lock(b)
{
//do stuff inside b, that involves leaving b in an inconsistent state
f();
//do more stuff inside b so that its consistent again
}
}
因此,我们的锁定订单得到了维护,当我们打电话
f()
时而无需自我锁定。
关键字使用重新输入锁,这意味着当前线程已经具有锁,因此它不会尝试重新征用它。如果僵局发生僵局。线程1获取锁a
线程2获取锁B
线程1试图获取锁定b(等待螺纹2使用它完成) 线程2尝试获取锁定A(等待线程1使用它)线程现在互相等待,因此陷入僵局。
从c#语言规范的第8.12
节:
虽然举行了相互限制的锁,但 在同一执行中执行代码 线程也可以获取并释放 锁。但是,在其他中执行代码 线程被阻止 锁定直到锁定锁。
应该很明显,内部lock
范围与外部相同的线程。