Why might neither thread finish when two locks are taken in opposite order?
Two threads each grab cup and coffeeMaker, but in opposite order. Explain why the program can hang, and how to fix it.
// thread 1
synchronized(cup) {
synchronized(coffeeMaker) { /* ... */ }
}
// thread 2
synchronized(coffeeMaker) {
synchronized(cup) { /* ... */ }
}
Diagnose the cause and fix it.
Thread 1 holds cup and waits for coffeeMaker; thread 2 holds coffeeMaker and waits for cup. Each waits on a lock the other holds — a deadlock, so neither proceeds. Fix it by acquiring both locks in one global order in every thread.
- ✗Assuming
synchronizedre-entrancy prevents deadlock across two objects - ✗Thinking the OS scheduler eventually breaks the deadlock on its own
- ✗Believing a different lock order in each thread is harmless
- →What four conditions must all hold for a deadlock to occur?
- →How could a
tryLockwith timeout avoid this hang instead of fixed ordering?
The bug
A classic deadlock from inconsistent lock-acquisition order:
// thread 1
synchronized(cup) { // holds cup
synchronized(coffeeMaker) { /* ... */ } // waits for coffeeMaker
}
// thread 2
synchronized(coffeeMaker) { // holds coffeeMaker
synchronized(cup) { /* ... */ } // waits for cup
}
Thread 1 holds cup and waits for coffeeMaker; thread 2 holds coffeeMaker and waits for cup. A circular wait forms and both hang forever.
The fix
Acquire the locks in a single global order in every thread — e.g. always cup first, then coffeeMaker:
// both threads
synchronized(cup) {
synchronized(coffeeMaker) { /* ... */ }
}
A consistent order breaks the circular-wait condition, making the deadlock impossible.