这种嵌套锁定会导致死锁吗?

本文关键字:死锁 嵌套 锁定 | 更新日期: 2023-09-27 18:09:57

Method1和Method2是公共方法。这两个方法都需要以相同的顺序接收两个锁。我确信以相同的顺序获取锁不会导致死锁。Common()中的锁是不必要的吗?

public void Method1()
{
    lock(LockObjA)
    lock(LockObjB)
    {
        //DoSomething
        Common();
    }
}
public void Method2()
{
    lock(LockObjA)
    lock(LockObjB)
    {
        //DoSomething else
        Common();
    }
}
private void Common()
{
    lock(LockObjA)
    lock(LockObjB)
    {
        //DoSomething else
    }
}

这种嵌套锁定会导致死锁吗?

我找不到更好的参考资料,但我记得我的操作系统课程中有资源锁定,教授说总是以相同的顺序获取资源不会增加发生死锁的机会。

总是以相同的顺序获取资源

编辑:找到一个关于这个的stackoverflow问题,但是仍然没有关于这个特定死锁预防机制的文章…

由于c#锁是可重入的,所以在使用代码时应该不会造成更多的伤害。

回到你的问题

如果所有方法都是私有的,那么在类中检查锁条件的作用域就很小。所以在公共API上,最好用锁来修饰所有改变可变状态的方法。即使这意味着它们可能会两次重新进入同一个锁。在私有API中,你可以决定是否合适。

Edit: After question Edit

如果这三个方法是作用域中唯一的方法,或者这三个方法是唯一的关键方法(修改/访问可变状态)。因为你看不到任何可以打破锁定的事情发生。

那么答案是肯定的!在Common方法中,锁是不必要的。

注:装饰方法

这里的装饰是指装饰者模式意义上的装饰。这意味着在一些代码之前和之后执行代码。在这种情况下,我指的是方法内部的代码。在java中存在一个synchronized关键字,它允许使用一个简短的手势来修饰方法内部的代码,方便地使用封闭实例对象的同步块。这被称为同步方法。