How to Create a Deadlock and Solve in Java

Learn to create a deadlock in Java programmatically, with an example. Also, learn to detect deadlock and how to solve a deadlock situation in source code.

Generally, if the program is not synchronized properly and system resources are shared among threads, there is always a chance of a deadlock situation, where multiple threads are waiting to access resources held by each other.

1. Simulating a Deadlock

In Java, a deadlock is a situation where a minimum of two threads are holding the lock on some different resource, and both are waiting for the other’s resource to complete its task. And, none is able to leave the lock on the resource it is holding.

deadlock scenario
Deadlock Scenario

In the above case, Thread-1 has A but need B to complete processing and similarly Thread-2 has resource B but need A first.

public class ResolveDeadLockTest {
 
  public static void main(String[] args) {
    ResolveDeadLockTest test = new ResolveDeadLockTest();
 
    final A a = test.new A();
    final B b = test.new B();
 
    // Thread-1
    Runnable block1 = new Runnable() {
      public void run() {
        synchronized (a) {
          try {
            // Adding delay so that both threads can start trying to
            // lock resources
            Thread.sleep(100);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          // Thread-1 have A but need B also
          synchronized (b) {
            System.out.println("In block 1");
          }
        }
      }
    };
 
    // Thread-2
    Runnable block2 = new Runnable() {
      public void run() {
        synchronized (b) {
          // Thread-2 have B but need A also
          synchronized (a) {
            System.out.println("In block 2");
          }
        }
      }
    };
 
    new Thread(block1).start();
    new Thread(block2).start();
  }
 
  // Resource A
  private class A {
    private int i = 10;
 
    public int getI() {
      return i;
    }
 
    public void setI(int i) {
      this.i = i;
    }
  }
 
  // Resource B
  private class B {
    private int i = 20;
 
    public int getI() {
      return i;
    }
 
    public void setI(int i) {
      this.i = i;
    }
  }
}

Running the above code will result in a deadlock for very obvious reasons (explained above). Now we have to solve this issue.

2. How to Solve a Deadlock?

I believe that the solution to any problem lies in identifying the root of the problem. In our case, it is the pattern of accessing the resources A and B, is main issue. So, to solve it, we will simply re-order the statements where the code is accessing shared resources.

// Thread-1
Runnable block1 = new Runnable() {
  public void run() {
    synchronized (b) {
      try {
        // Adding delay so that both threads can start trying to
        // lock resources
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      // Thread-1 have A but need B also
      synchronized (a) {
        System.out.println("In block 1");
      }
    }
  }
};
 
// Thread-2
Runnable block2 = new Runnable() {
  public void run() {
    synchronized (b) {
      // Thread-2 have B but need A also
      synchronized (a) {
        System.out.println("In block 2");
      }
    }
  }
};

Run again above class, and you will not see any deadlock kind of situation. I hope it will help you avoid deadlocks and, if encountered, resolve them.

Happy Learning !!

Leave a Reply

16 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial