为什么嵌套的锁不会造成僵局? [重复]

问题描述 投票:0回答:2

为什么此代码不会导致僵局?

private static readonly object a = new object();
...

lock(a) { lock(a) { .... } }
    
c# asp.net multithreading deadlock thread-synchronization
2个回答
59
投票
如果线程已经锁定锁,那么它可以再次“锁定”而无需问题。

为什么是,也就是(为什么这是一个好主意)考虑以下情况,在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使用它)

线程现在互相等待,因此陷入僵局。

27
投票

从c#语言规范的第8.12

节:

虽然举行了相互限制的锁,但 在同一执行中执行代码 线程也可以获取并释放 锁。但是,在其他中执行代码 线程被阻止 锁定直到锁定锁。

应该很明显,内部
lock
范围与外部相同的线程。

© www.soinside.com 2019 - 2025. All rights reserved.