Deadlock, livelock and diagnostics question 138 of 180 mid
Show the classic transfer deadlock and fix it.
- Synchronize the whole transfer method
- Correct: Opposite lock order on the two accounts; fix with a consistent global order or
tryLock - Use a
ConcurrentHashMapof accounts - Make the balances volatile
void transfer(Account from, Account to, long amount) {
synchronized (from) {
synchronized (to) { ... } // transfer(a, b) and transfer(b, a) deadlock
}
}
The ordered fix picks a total order over accounts and always locks in that order:
Account first = from.id() < to.id() ? from : to;
Account second = from.id() < to.id() ? to : from;
synchronized (first) {
synchronized (second) { ... }
}
If there is no natural id, use System.identityHashCode plus a tie-break lock for the collision case.
The alternative is tryLock on the second account with a timeout, releasing the first and retrying
after a random backoff, which also handles locks you do not control.
Quiz yourself on Deadlock, livelock and diagnostics Suggest a correction