为什么不locking相同的对象导致死锁?

可能重复:
C#中的重入锁

如果我写这样的代码:

class Program { static void Main(string[] args) { Foo(); Console.ReadLine(); } static void Foo() { lock(_lock) { Console.WriteLine("Foo"); Bar(); } } static void Bar() { lock(_lock) { Console.WriteLine("Bar"); } } private static readonly object _lock = new object(); } 

我得到输出:

 Foo Bar 

我预料到这会陷入僵局,因为Foo获得一个锁,然后等待Bar获得锁。 但是这不会发生。

locking机制是否只是允许这个,因为代码是在同一个线程上执行的?

对于同一个线程,一个锁总是可重入的 ,所以线程可以locking一个对象。

因为你在这里只有一个线程。

lock是捷径

 bool lockWasTaken = false; var temp = obj; try { Monitor.Enter(temp, ref lockWasTaken); // your thread safe code } finally { if (lockWasTaken) Monitor.Exit(temp); } 

Monitor.Enter获取作为parameter passing的对象上的Monitor。 如果另一个线程在对象上执行了一个Enter但尚未执行相应的Exit,则当前线程将被阻塞,直到另一个线程释放该对象。 同一个线程在不阻塞的情况下多次调用Enter是合法的 ; 但是,等待对象的其他线程将被解除阻塞之前,必须调用相同数量的Exit调用。

lock语句比这更聪明,它的目的是防止这一点。 当线程进入locking状态时,该线程将“拥有”该locking,所以只要lock到另一个lock同一个对象的lock语句,就会意识到它已经可以访问该locking。

一个字:可重入锁。 如果一个线程已经获得一个锁,那么如果它想要再次获得该锁,则不等待。 这是非常需要的,否则它可能会把简单的recursion函数变成一场噩梦。