C#中的重入锁定

Guy*_*Guy 116 .net c# multithreading deadlock locking

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

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

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

    public void Bar()
    {
        lock(lockObj)
        { 
          // Do something 
        }
    }       
 }
Run Code Online (Sandbox Code Playgroud)

Nei*_*ell 143

不,只要你锁定同一个对象就行了.递归代码实际上已经具有锁定,因此可以继续不受阻碍.

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

如果你开始锁定不同的对象,那就是你需要小心的时候.特别注意:

  • 始终以相同的顺序获取给定数量的对象上的锁.
  • 始终按照与获取方式相反的顺序释放锁定.

如果你破坏了这些规则中的任何一个,你几乎可以保证在某些时候出现死锁问题.

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

此外,尽可能锁定尽可能少的对象.考虑尽可能使用粗粒度锁.我们的想法是,如果您可以编写代码,使得存在对象图,并且您可以获取该对象图的根上的锁,那么就这样做.这意味着您对该根对象有一个锁,因此不必担心获取/释放锁的顺序.

(还有一点需要注意,你的例子在技术上并不是递归的.因为它是递归的,所以Bar()必须自己调用,通常作为迭代的一部分.)

  • 再递归; 确实; 为了盖伊的利益,这个词是可重入的 (6认同)

Mar*_*ell 19

好吧,Monitor允许重新进入,所以你不能让自己陷入僵局......所以不:它不应该这样做


Jef*_*dge 6

如果一个线程已经持有一个锁,那么它就不会阻塞自己..Net框架确保了这一点.你只需要确保两个线程不要试图用任何的代码路径将收购相同的两个锁失序.

同样的线程可以AQUIRE相同的锁多次,但你必须确保你解除锁定相同数量的,你AQUIRE它倍.当然,只要您使用"lock"关键字来完成此操作,它就会自动发生.


Ris*_*ain 5

不,这段代码不会有死锁.如果你真的想创建最简单的死锁,那么至少需要2个资源.考虑狗和骨头场景.一条狗可以完全控制一根骨头,所以任何其他狗都要等.2.当他们分别锁住骨头并寻找其他骨头时,最少需要2只带有2块骨头的狗来制造死锁.

......等等n狗和骨头,造成更复杂的死锁.