可能重复:
Re-entrant locks in 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获得锁。但这不会发生。
锁定机制是否只允许这样做,因为代码是在同一个线程上执行的?
答案 0 :(得分:75)
对于同一个线程,锁始终是reentrant,因此线程可以根据需要随时锁定对象。
答案 1 :(得分:21)
因为这里只有一个帖子。
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获取作为参数传递的对象的Monitor。如果另一个线程在对象上执行了Enter但尚未执行相应的Exit,则当前线程将阻塞,直到另一个线程释放该对象。 同一个线程在没有阻止的情况下多次调用Enter是合法的;但是,在等待对象的其他线程将解除阻塞之前,必须调用相同数量的Exit调用。
答案 2 :(得分:8)
一个字:可重入锁定。如果一个线程已经获得了一个锁,那么如果它想要再次获取锁,它就不会等待。这是非常需要的,否则它可能会将简单的递归函数变成一场噩梦。!
答案 3 :(得分:5)
lock
语句比这更聪明,它旨在防止这种情况发生。一旦线程进入其中,锁就被“拥有”,所以当它到达锁定同一对象的另一个lock
语句时,它将意识到它已经可以访问该锁。