C# 为什么';t锁';在同一个对象上重新启动会导致死锁吗?

C# 为什么';t锁';在同一个对象上重新启动会导致死锁吗?,c#,.net,locking,deadlock,C#,.net,Locking,Deadlock,可能重复: 如果我写一些这样的代码: class Program { static void Main(string[] args) { Foo(); Console.ReadLine(); } static void Foo() { lock(_lock) { Console.WriteLine("Foo"); Bar(); } } st

可能重复:

如果我写一些这样的代码:

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获取锁。但这并没有发生


由于代码在同一个线程上执行,锁定机制是否只允许这样做?

因为这里只有一个线程

锁定

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

获取作为参数传递的对象上的监视器。如果另一个线程已对对象执行Enter,但尚未执行相应的Exit,则当前线程将阻塞,直到另一个线程释放该对象同一线程在不阻止Enter的情况下多次调用Enter是合法的;但是,在等待对象的其他线程解除阻止之前,必须调用相同数量的退出调用。

对于同一线程,总是有一个锁,因此线程可以根据需要随时锁定对象。

lock语句比这更聪明,它的设计目的就是防止这种情况发生。一旦锁进入线程,它就被线程“拥有”,因此每当它到达另一个锁定同一对象的
lock
语句时,它就会意识到它已经可以访问该锁了。

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

+1关键字为“可重入”;不可重入的锁(例如文件锁)会死锁。多亏了,可重入是我所缺少的术语,这也是为什么我无法在Google上快速找到答案的原因。如果一个线程可以多次获取锁,并且必须多次释放锁,则称之为递归。虽然在C#中可能不是这样,但正如您所知。+1表示在单独的线程访问之前,退出调用的数量相等permission@JaroslawWaliszko重新输入后重新退出:)+1表示递归常见感觉词:两个词。顺便说一下,这有点离题,但我认为知道这一点很好“锁不是你撒在代码上的魔法灰尘,它会突然变得安全。”: