为什么嵌套锁不会导致死锁?
为什么这段代码不会导致死锁?
private static readonly object a = new object();
...
lock(a)
{
lock(a)
{
....
}
}
Why does this code not cause a deadlock?
private static readonly object a = new object();
...
lock(a)
{
lock(a)
{
....
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果线程已经持有锁,那么它可以毫无问题地再次“获取该锁”。
至于为什么(以及为什么这是一个好主意),请考虑以下情况,其中我们在 a -> 程序的其他地方定义了锁定顺序。 b:
哎呀,我们刚刚违反了我们的锁定顺序,并且我们手上有一个潜在的死锁。
我们确实需要能够执行以下操作:
以便在调用
f()
时保持我们的锁顺序,而不会出现自死锁。If a thread already holds a lock, then it can "take that lock" again without issue.
As to why that is, (and why it's a good idea), consider the following situation, where we have a defined lock ordering elsewhere in the program of a -> b:
Whoops, we just violated our lock ordering and have a potential deadlock on our hands.
We really need to be able to do the following:
So that our lock ordering is maintained, without self-deadlocking when we call
f()
.lock
关键字使用可重入锁,这意味着当前线程已经拥有该锁,因此不会尝试重新获取它。则会发生死锁
如果线程 1 获取锁 A,
线程 2 获取锁 B
线程 1 尝试获取锁 B(等待线程 2 完成操作)
线程 2 尝试获取锁 A(等待线程 1 完成该操作),
两个线程现在都在互相等待,因此陷入死锁。
The
lock
keyword uses a re-entrant lock, meaning the current thread already has the lock so it doesn't try to reacquire it.A deadlock occurs if
Thread 1 acquires lock A
Thread 2 acquires lock B
Thread 1 tries to acquire lock B (waits for Thread 2 to be done with it)
Thread 2 tries to acquire lock A (waits for Thread 1 to be done with it)
Both threads are now waiting on each other and thus deadlocked.
来自 C# 语言规范的 第 8.12 节:
很明显,内部锁定范围与外部锁定范围位于同一线程中。
From section 8.12 of the C# language specification:
It should be obvious that the internal
lock
scope is in the same thread as the outer.