How to Avoid Deadlock in Java

How to Solve Deadlock using Threads in Java?

Java programming language supports multithreading. It involves multiple threads running simultaneously for multitasking. But in certain cases or due to certain shortcomings, the threads find themselves in the waiting state forever. In this article, We will understand the deadlock condition in Java and different ways to avoid it. The following are the topics discussed in this article:

  • What is Deadlock in Java?
  • Deadlock Example
  • How To Avoid Deadlock in Java?

What is Deadlock in Java?

Deadlock in Java is a condition where two or more threads are blocked forever, waiting for each other.

This usually happens when multiple threads need the same locks but obtain them in different orders. Multithreaded Programming in Java suffers from the deadlock situation because of the synchronized keyword.

It causes the executing thread to block while waiting for the lock, or monitor, associated with the specified object.

Example: #1
Example: #2

Code Example of Deadlock in Java

The following code example illustrates a deadlock situation in Java:

Method 1
/*
 * Author: Zameer Ali
 * */
public class MyThreadDeadlockDemo {
    public static Object lockObjectA = new Object();
    public static Object lockObjectB = new Object();
    public static void main(String args[]) {
        MyThreadClassA threadObjectA = new MyThreadClassA();
        MyThreadClassB threadObjectB = new MyThreadClassB();

        threadObjectA.start();
        threadObjectB.start();
    }

    private static class MyThreadClassA extends Thread {
        public void run() {
            synchronized(lockObjectA) {
                System.out.println("Thread A: Acquired lock A");

                try {
                    Thread.sleep(100);
                } catch (Exception ex) {}
                System.out.println("Thread A: Waiting for lock B");
                synchronized(lockObjectB) {
                    System.out.println("Thread A: Acquired lock on A and B");
                }
            }
        }
    }
    private static class MyThreadClassB extends Thread {
        public void run() {
            synchronized(lockObjectB) {
                System.out.println("Thread B: Acquired lock B");

                try {
                    Thread.sleep(100);
                } catch (Exception ex) {}
                System.out.println("Thread B: Waiting for lock A");

                synchronized(lockObjectA) {
                    System.out.println("Thread B: Acquired lock on A and B");
                }
            }
        }
    }
}