为什么这段代码没有死锁
本文关键字:死锁 代码 段代码 为什么 | 更新日期: 2023-09-27 18:34:25
我希望当 Clear 尝试锁定 Build 已锁定的同一对象时,以下代码将死锁:
void Main()
{
(new SiteMap()).Build();
}
class SiteMap
{
private readonly object _lock = new object();
public void Build()
{
lock (_lock)
{
Clear();
Console.WriteLine("Build");
}
}
public void Clear()
{
lock (_lock)
{
Console.WriteLine("Clear");
}
}
}
输出:
清楚
建
编辑 1
谢谢大家的回答。
如果我在 Clear 锁中添加对 Build 的调用(保持代码的其余部分相同):
public void Clear()
{
lock (_lock)
{
Build();
Console.WriteLine("Clear");
}
}
确实会发生死锁(或者至少我认为是这样,LINQ Pad 崩溃)。
根据您的回答,这不应该发生,因为它仍然是相同的线程。
谢谢!
在 C# 中,持有锁的线程可以进入同一锁而不会阻塞。
lock
语句以及生成该语句的监视器类在 .NET 中是可重入的。
编辑
以响应您的编辑:
当您将调用添加到 clear 内部Build
时,代码不会死锁 - 它会递归调用自身。 它不是阻塞,而是永远运行(直到最终你遇到 StackOverflowException),因为Build
调用Clear
再次调用Build
调用Clear
,等等......
lock
的文档说:
如果另一个线程尝试输入锁定的代码,它将等待(阻止)直到对象被释放。
关键词是"另一个"。线程不会阻塞自身,只会阻塞其他线程。如果另一个线程拥有锁,那么lock
就会阻塞。
这样可以省去很多麻烦。
我不会,因为在已经应用锁的同一线程中调用了 clear。