Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this code deadlock?

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!

like image 766
stacker Avatar asked May 17 '12 17:05

stacker


1 Answers

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....

like image 139
Reed Copsey Avatar answered Sep 27 '22 22:09

Reed Copsey