Deadlock in Java
Introduction
Deadlock is a situation in multithreading where two or more threads are blocked forever, each waiting for the other to release a resource. It is one of the most common concurrency problems and a favorite interview question.
Example of Deadlock
class DeadlockExample {
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public void method1() {
synchronized(lock1) {
System.out.println("Thread 1: Holding lock1...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized(lock2) {
System.out.println("Thread 1: Holding lock1 & lock2...");
}
}
}
public void method2() {
synchronized(lock2) {
System.out.println("Thread 2: Holding lock2...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized(lock1) {
System.out.println("Thread 2: Holding lock2 & lock1...");
}
}
}
public static void main(String[] args) {
DeadlockExample example = new DeadlockExample();
new Thread(example::method1).start();
new Thread(example::method2).start();
}
}
Explanation: Thread 1 holds lock1 and waits for lock2, while Thread 2 holds lock2 and waits for lock1. Neither can proceed β deadlock.
Conditions for Deadlock
- Mutual Exclusion: Resources cannot be shared.
- Hold and Wait: A thread holds one resource and waits for another.
- No Preemption: Resources cannot be forcibly taken away.
- Circular Wait: Threads form a cycle waiting for each otherβs resources.
Prevention Strategies
- Lock Ordering: Always acquire locks in a consistent global order.
- Timeouts: Use
tryLock()with timeout to avoid waiting indefinitely. - Avoid Nested Locks: Minimize situations where a thread holds multiple locks.
- Use Concurrency Utilities: Prefer
ConcurrentHashMap,BlockingQueue, etc., which are designed to avoid deadlocks.
Comparison Table
| Aspect | Deadlock | Prevention |
|---|---|---|
| Definition | Threads wait forever for each otherβs resources | Design strategies to avoid cyclic waiting |
| Cause | Mutual exclusion + hold & wait + no preemption + circular wait | Break one of the conditions |
| Example | Thread 1 holds lock1, waits for lock2; Thread 2 holds lock2, waits for lock1 | Acquire locks in same order, use tryLock |
Interview-Ready Notes
- Definition: Deadlock is when threads wait forever due to circular dependency.
- Key Point: Mention the four necessary conditions for deadlock.
- Prevention: Stress lock ordering and timeouts as practical solutions.
- Best Practice: Use high-level concurrency utilities to reduce manual lock management.
- Common Question: βHow do you detect deadlock?β β By analyzing thread dumps with tools like
jstack.
Conclusion
Deadlock is a critical concurrency issue that can halt applications. By understanding its causes and applying prevention strategies like lock ordering, timeouts, and concurrency utilities, developers can design robust multithreaded applications. In interviews, emphasize both the definition and practical prevention techniques to demonstrate mastery.