Introduction

A deadlock is a situation where an application locks up because two or more activities are waiting for each other to finish. This occurs in multithreading software where a shared resource is locked by one thread and another thread is waiting to access it and something occurs so that the thread holding the locked item is waiting for the other thread to execute.

First, it's important to understand what a deadlock among threads is and the conditions that lead to one. Many OS course textbooks will cite the four conditions necessary for a deadlock to occur:

lock(a)
{
lock(b)
{
....
}
}

If any one of these conditions is not met, deadlock is not possible. We can avoid all four condition by the followings:

To further illustrate how a deadlock might occur, imagine the following sequence of events:

At this point, both threads are blocked and will never wake up. The following C# code demonstrates this situation.

object lockA = new object();
object lockB = new object();
Thread 1 void t1()
{
lock (lockA)
{
lock (lockB)
{
/* ... */
}
}
}
Thread 2 void t2()
{
lock (lockB)
{
lock (lockA)
{
/* ... */
}
}
}

We have another code which demonstrate the deadlock condition as:

using System;
using System.Threading;
namespace deadlockincsharp
{
public class Akshay
{
static readonly object firstLock = new object();
static readonly object secondLock = new object();
static void ThreadJob()
{
Console.WriteLine("\t\t\t\tLocking firstLock");
lock (firstLock)
{
Console.WriteLine("\t\t\t\tLocked firstLock");
// Wait until we're fairly sure the first thread
// has grabbed secondLock
Thread.Sleep(1000);
Console.WriteLine("\t\t\t\tLocking secondLock");
lock (secondLock)
{
Console.WriteLine("\t\t\t\tLocked secondLock");
}
Console.WriteLine("\t\t\t\tReleased secondLock");
}
Console.WriteLine("\t\t\t\tReleased firstLock");
}
static void Main()
{
new Thread(new ThreadStart(ThreadJob)).Start();
// Wait until we're fairly sure the other thread
// has grabbed firstLock
Thread.Sleep(500);
Console.WriteLine("Locking secondLock");
lock (secondLock)
{
Console.WriteLine("Locked secondLock");
Console.WriteLine("Locking firstLock");
lock (firstLock)
{
Console.WriteLine("Locked firstLock");
}
Console.WriteLine("Released firstLock");
}
Console.WriteLine("Released secondLock");
Console.Read();
}
}
}

Output

deadlock.gif

(You'll need to hit Ctrl-C or something similar to kill the program.) As you can see, each thread grabs one lock and then tries to grab the other. The calls to Thread.Sleep have been engineered so that they will try to do so at inopportune times, and deadlock.