一尘不染

C#中的重入锁

c#

以下代码是否会在.NET上使用C#导致死锁?

 class MyClass
 {
    private object lockObj = new object();

    public void Foo()
    {
        lock(lockObj)
        { 
             Bar();
        }
    }

    public void Bar()
    {
        lock(lockObj)
        { 
          // Do something 
        }
    }       
 }

阅读 549

收藏
2020-05-19

共1个答案

一尘不染

不,只要您锁定在同一对象上即可。递归代码实际上 已经具有锁定 ,因此可以不受阻碍地继续进行。

lock(object) {...}是使用Monitor类的简写。正如Marc指出的那样Monitor允许
重新进入 ,因此反复尝试锁定
当前线程已经具有锁定的对象 将很好。

如果您开始锁定 其他 对象,则必须小心。请特别注意:

  • 始终以相同的顺序获取给定数量的对象上的锁。
  • 始终以与获取锁 相反的 顺序释放锁。

如果您违反了这两个规则,则肯定可以 在某些时候 遇到死锁问题。

这是一个描述.NET中线程同步的好网页:http : //dotnetdebug.ne​​t/2005/07/20/monitor-class-avoiding-
deadlocks/

另外,一次锁定尽可能少的对象。考虑在可能的情况下应用粗粒度的锁。这样的想法是,如果您可以编写代码以使有一个对象图,并且可以获取该对象图的根上的锁,则可以这样做。这意味着您在该根对象上拥有一个锁,因此不必太担心获取/释放锁的顺序。

(还要注意,您的示例在技术上不是递归的。要使其具有递归性Bar(),通常必须在迭代过程中调用自身。)

2020-05-19