March 23, 2024

How to Create a Deadlock in Java

If you are asked what is deadlock in Java it is almost always accompanied by the question how to create a deadlock in Java.

Deadlock in multi-threading is a scenario where two or more threads are waiting for each other to release the resources to make any further progress and blocked forever in the process.

Java program for creating deadlock

You may get deadlock in Java when you have nested synchronized blocks with reverse ordering of objects.

In the example two threads are created to run two separate runnable tasks. In each runnable task there are nested synchronized blocks acquiring object locks in reversed order thus creating a deadlock.

class ThreadA implements Runnable{
  private Object obj1;
  private Object obj2;
  ThreadA(Object obj1, Object obj2){
    this.obj1 = obj1;
    this.obj2 = obj2;
  }
  @Override
  public void run() {
    synchronized(obj1){
      System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
      System.out.println(Thread.currentThread().getName() + " waiting for " + "obj2 lock");
      synchronized(obj2){
        System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
      }
    }       
  }  
}
 
class ThreadB implements Runnable{
  private Object obj1;
  private Object obj2;
  ThreadB(Object obj1, Object obj2){
    this.obj1 = obj1;
    this.obj2 = obj2;
  }
  @Override
  public void run() {
    synchronized(obj2){
      System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
      System.out.println(Thread.currentThread().getName() + " waiting for " + "obj1 lock");
      synchronized(obj1){
        System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
      }
    }   
  }
}

public class DLDemo {
  public static void main(String[] args) {
    Object obj1 = new Object();
    Object obj2 = new Object();
    Thread t1 = new Thread(new ThreadA(obj1, obj2));
    Thread t2 = new Thread(new ThreadB(obj1, obj2));
    t1.start();
    t2.start();
  }
}
Output
Thread-0 acquired obj1 lock
Thread-0 waiting for obj2 lock
Thread-1 acquired obj2 lock
Thread-1 waiting for obj1 lock

You can see in run() method of ThreadA synchronized block acquires lock on obj1 and then tries to acquire lock on obj2. Same way in run() method of ThreadB synchronized block acquires lock on obj2 and then tries to acquire lock on obj1. This hangs the program by creating a deadlock as t1 thread is waiting to acquire lock on obj2 which is currently acquired by t2 thread and t2 thread is waiting to acquire lock on obj1 which is currently acquired by the t1 thread.

Creating deadlock by calling one synchronized method from another

Here is another example of creating deadlock in Java. It is similar to the first example here rather than having nested synchronized blocks there are two synchronized methods. The objects which are used to call the method and the object which are passed as an argument to these methods are reversed thus creating deadlock.

public class DLDemo {
  public synchronized void method1(DLDemo obj){
    System.out.println(Thread.currentThread().getName() + " In Method1");
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    //Calling another synchronized method
    obj.method2(this);
  }
			  
  public synchronized void method2(DLDemo obj2){
    System.out.println("In Method2");
  }
 
  public static void main(String[] args) {
    DLDemo obj1 = new DLDemo();
    DLDemo obj2 = new DLDemo();
   
    new Thread(new Runnable() {
      public void run() { obj1.method1(obj2); }
    }).start();

    //Thread 2  
    new Thread(new Runnable() {
      public void run() { obj2.method1(obj1); }
    }).start();
  }
}
Output
Thread-0 In Method1
Thread-1 In Method1

From one thread synchronized method method1 is called using obj1 so this thread acquires a lock on obj1 then another synchronized method method2 is called using obj2.

From another thread synchronized method method1 is called using obj2 so this thread acquires a lock on obj2 then another synchronized method method2 is called using obj1.

That's all for the topic How to Create a Deadlock in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment