eraserpeel
eraserpeel

Reputation: 16

C#: Why does one of these threading examples deadlock and the other doesn't?

The follow code will lock:

static void Main()
{
    object lockA = new object();
    object lockB = new object();
    var up = Task.Run(() =>
    {
        lock (lockA)
        {
            Thread.Sleep(1000);
            lock (lockB)
            {
                Console.WriteLine("Here1");
            }
        }
    });
    var down = Task.Run(() =>
    {
        lock (lockB)
        {
            lock (lockA)
            {
                Console.WriteLine("Here2");
            }

        }
    });
    up.Wait();
    Console.ReadLine();
}

But this code, taken from the C# .NET 70-483 book doesn't lock in Visual Studio 2013 running under debug mode.

static void Main()
        {
            object lockA = new object();
            object lockB = new object();
            var up = Task.Run(() =>
            {
                lock (lockA)
                {
                    Thread.Sleep(1000);
                    lock (lockB)
                    {
                        Console.WriteLine("Here1");
                    }
                }
            });
            lock (lockB)
            {
                lock (lockA)
                {
                    Console.WriteLine("Here2");
                }

            }
            up.Wait();
            Console.ReadLine();
        }

Is there something special about the thread that main is running in or is there some simple detail in the implementation that I can't see. It doesn't say anything here: https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx that would give me an indication as to why.

My only other idea would be that the thread in which "up" was spawned has some special ability to enter a lock? If this is the reason why would that be important to allow your code to do?

Upvotes: 0

Views: 62

Answers (1)

Aasmund Eldhuset
Aasmund Eldhuset

Reputation: 37940

It's just random timing; in the second example, both locks around the second printing are probably entered before the thread for the first task has the time to start up. Add Thread.Sleep(500) before the last lock (lockB), and you'll probably see it lock up too.

Upvotes: 1

Related Questions