How does a deadlock happen in Java and how can you avoid it?
A deadlock occurs when threads each hold one lock and wait forever for a lock the other holds. Avoid it by always acquiring locks in the same order, holding fewer locks, or using tryLock with a timeout.
Explain it simply
Two friends share a pen and a notebook. Asha holds the pen and waits for the notebook, Bhavin holds the notebook and waits for the pen. Neither lets go, so both wait forever.
Example
Object pen = new Object();
Object notebook = new Object();
Thread asha = new Thread(() -> {
synchronized (pen) {
sleepBriefly();
synchronized (notebook) { System.out.println("Asha writes"); }
}
});
Thread bhavin = new Thread(() -> {
synchronized (notebook) { // opposite order -> possible deadlock
sleepBriefly();
synchronized (pen) { System.out.println("Bhavin writes"); }
}
});
// Fix: make both threads lock pen first, then notebook.What to say in the interview
"Deadlock needs four conditions together: mutual exclusion, hold and wait, no preemption, and a circular wait. The simplest fix is to break the circle by imposing a global lock order, so every thread takes pen before notebook. Other options are using ReentrantLock.tryLock with a timeout, keeping critical sections small, or avoiding nested locks. To diagnose one, take a thread dump with jstack, which reports the deadlocked threads."
Common mistakes
- Thinking synchronized blocks time out by themselves. They wait forever.