Java Concurrency Interview

Deadlock, livelock and diagnostics question 138 of 180 mid

Show the classic transfer deadlock and fix it.

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.

deadlock lock-ordering

Quiz yourself on Deadlock, livelock and diagnostics Suggest a correction