What is a deadlock in Java and how to avoid it?

Thread A locks lock1 and waits for lock2. Thread B locks lock2 and waits for lock1. Both wait for ever.

public class Main {
    static final Object lock1 = new Object();
    static final Object lock2 = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread a = new Thread(() -> {
            synchronized (lock1) {
                pause();
                synchronized (lock2) { System.out.println("A done"); }
            }
        });
        Thread b = new Thread(() -> {
            synchronized (lock2) {
                pause();
                synchronized (lock1) { System.out.println("B done"); }
            }
        });
        a.setDaemon(true);
        b.setDaemon(true);
        a.start();
        b.start();

        a.join(1500);
        b.join(1500);
        System.out.println("A alive: " + a.isAlive() + ", B alive: " + b.isAlive());
    }

    static void pause() {
        try { Thread.sleep(300); } catch (InterruptedException e) { }
    }
}
Output

A alive: true, B alive: true

Both threads are still alive after waiting, so they are in a deadlock. How to avoid it:

  • Always take the locks in the same order in all threads.
  • Use tryLock(timeout) of ReentrantLock and give up after some time.
  • Keep the locked code small and do not call unknown code inside it.
  • Prefer high level tools (ExecutorService, concurrent collections).

Learn more about the similar topics:
Tutorials
No Content Found.
Exercises & Assignments
No Content Found.
Interview Questions & Answers
No Content Found.