How to programmatically create a deadlock scenario in Java

What is a deadlock?

A deadlock is when two or more processes share common resources and hold some resource while waiting for another resource that is acquired by the other processes.

Let’s take a real-life scenario. We have a desktop and laptop, as well as two resources: a printer and a scanner. The desktop is accessing the printer and locked it, while the laptop is accessing the scanner and locked it.

  • Desktop lockedlocked printer.
  • Laptop lockedlocked scanner.
Real life example of Deadlock

Now, the scanner will not be available for the desktop, as it is already acquired by the desktop. The same goes for the printer. Hence, this situation is a deadlock.

Code

Let’s take a look at the code now.

class DeadLock {
static final String resource1= "Printer";
static final String resource2= "Scanner";
public static void main(String[] args) {
ThreadDemo1 Thread1 = new ThreadDemo1();
ThreadDemo2 Thread2 = new ThreadDemo2();
Thread1.start();
Thread2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (resource1) {
System.out.println("Desktop "+ ": locked" + resource1);
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
System.out.println("Desktop " + ": waiting for" + resource2+"......");
synchronized (resource2) {
System.out.println("Desktop "+ ": locked" + resource2);
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (resource2) {
System.out.println("Laptop "+": locked" + resource2);
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
System.out.println("Laptop " + ": waiting for" + resource1+"......");
synchronized (resource1) {
System.out.println("Laptop "+ ": locked" + resource1);
}
}
}
}

Explanation

  • In lines 2 and 3, we create Scanner and Printer.

  • In line 4, inside the main() function, we create two objects of ThreadDemo1 and ThreadDemo2 class and call them with the start() method.

  • From lines 10 to 24, inside the ThreadDemo1 class, we implement the run() method (as we have extended the ThreadDemo1 class from the built-in Thread class), and acquire the lock on resource1 (printer).

  • Then, in line 15, we put the thread on sleep, and in line 19, we demand resource2 (scanner) by the desktop.

  • From lines 25 to 39, inside the ThreadDemo2 class, we implement the run() method and acquire the lock on resource2 (scanner). We put the thread on sleep and demand resource1 (printer) by the laptop.

  • We use synchronized() to first acquire a lock on printer for desktop and put it in wait, then we do the same thing for scanner. Hence, the printer will be locked by desktop, and scanner by laptop, and both desktop and laptop need the scanner and printer, respectively, to terminate the process.

Both the threads will create a deadlock scenario.

Free Resources