Reputation: 53
I expect the following code to deadlock when Clear tries to lock on the same object that Build has already locked:
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");
}
}
}
Output:
Clear
Build
Edit 1
Thank you all for your answers.
If I add a call to Build inside the lock of Clear (keeping the rest of the code the same):
public void Clear()
{
lock (_lock)
{
Build();
Console.WriteLine("Clear");
}
}
A deadlock does occur (or at least that's what I think, LINQ Pad crashes).
According to your answers, this shouldn't happen, because it's still the same thread.
Thanks!
Upvotes: 5
Views: 191
Reputation: 564333
In C#, a thread holding a lock can enter the same lock without blocking.
The lock
statement, as well as the Monitor class on which it is built, is reentrant in .NET.
Edit in response to your edit:
When you add the call to Build
inside clear, the code doesn't deadlock - it is calling itself recursively. It's not blocking, but rather running forever (until, eventually, you hit a StackOverflowException), because Build
calls Clear
which calls Build
again which calls Clear
, etc....
Upvotes: 8
Reputation: 385546
The documentation for lock
says:
If another thread attempts to enter a locked code, it will wait (block) until the object is released.
The key word is "another". A thread does not block itself, just other threads. If another thread had owned the lock, then lock
would block.
This saves a lot of headaches.
Upvotes: 5
Reputation: 2591
I will not because clear is called within the same thread which already applied the lock.
Upvotes: 4