Jon
Jon

Reputation: 40032

Creating a deadlock

I have some code that looks like the below. Does this create a deadlock?

private readonly object objectLock = new object();

public void MethodA()
{
    lock(objectLock)
    {
       MethodB();
    }
}

public void MethodB()
{
    lock(objectLock)
    {
      //do something
    }
}

UPDATE: There will 2 threads running

Upvotes: 4

Views: 1514

Answers (5)

RotatingWheel
RotatingWheel

Reputation: 1049

If you copy paste the following lines, compile and run see that "never called" is not printed in the console.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace deadlocktest
{
    class Program
    {
    static object object1 = new object();
    static object object2 = new object();

    public static void FunctionOne()
    {
        lock (object1)
        {
            Console.WriteLine("FunctionOne called 1");
            Thread.Sleep(1000);
            lock (object2)
            {
                Console.WriteLine("FunctionOne called 2, never called");
            }
        }
    }

    public static void FunctionTwo()
    {
        lock (object2)
        {
            Console.WriteLine("FunctionTwo called 1");
            Thread.Sleep(1000);
            lock (object1)
            {
                Console.WriteLine("FunctionTwo called 2, never called");
            }
        }
    }

    static void Main(string[] args)
    {

        Thread thread1 = new Thread(FunctionOne);
        Thread thread2 = new Thread(FunctionTwo);
        thread1.Start();
        thread2.Start();
        int i = 0;
        while (i < 9)
        {
            Console.WriteLine("How bad thread!");
            i++;
        }
        thread1.Join();
        thread2.Join();
        Console.ReadLine();
    }
}

}

Upvotes: 1

Branko Dimitrijevic
Branko Dimitrijevic

Reputation: 52107

If this is the only mutex involved, it isn't. The same thread can lock the same mutex multiple times, as long it unlocks it equal number of times.

Calling MethodA produces the following sequence of operations on the same thread:

  • Lock objectLock.
  • Call MethodB.
  • Lock objectLock.
  • Unlock objectLock.
  • Exit MethodB.
  • Unlock objectLock.

So, objectLock is locked twice and unlocaked twice, but there is no deadlock:

  • If another thread tries to call MethodA it will simply block on the first lock but will not deadlock.
  • It if calls MethodB, the same would happen.
  • And if first thread call MethodB and then other thread calls MethodA, again "normal" blocking would take place but not a deadlock.

Upvotes: 3

Yahia
Yahia

Reputation: 70369

No - but this would be:

private readonly object objectLockA = new object();
private readonly object objectLockB = new object();

public void MethodA()
{
    lock(objectLockA)
    {
    lock(objectLockB)
    {
       //...
    }
    }
}

public void MethodB()
{
    lock(objectLockB)
    {
    lock(objectLockA)
    {
      //do something
    }
    }
}

If you call both Methods in parallel (from 2 different threads) then you would get a deadlock...

Upvotes: 11

Muhammad Hasan Khan
Muhammad Hasan Khan

Reputation: 35126

No its not a deadlock. Its the same thread locking on the same synchronization object. A thread can take nested locks. It just needs to release it equal no. of times.

Upvotes: 6

Paul Mitchell
Paul Mitchell

Reputation: 3281

No, you'd need two lock objects to enable a deadlock.

Upvotes: 3

Related Questions