Medium java java-21

What are deadlock, starvation, livelock and race conditions?

The 30 second answer

A deadlock is when two threads each hold a lock the other needs, so both wait forever. Starvation is when one thread rarely gets a resource because others keep taking it. Livelock is when threads keep reacting to each other but make no progress. A race condition is when the result depends on timing, like two threads incrementing the same counter. Fixes: consistent lock order, timeouts, and atomic or concurrent classes.

Classic deadlock and the fix:

// Thread 1: lock(a) then lock(b);  Thread 2: lock(b) then lock(a)  -> deadlock
void transfer(Account from, Account to, long amt) {
    Account first  = from.id() < to.id() ? from : to;   // global lock order
    Account second = first == from ? to : from;
    synchronized (first) { synchronized (second) { from.debit(amt); to.credit(amt); } }
}

Prevention:

  • Deadlock: acquire locks in a fixed order; use tryLock with a timeout; don't call unknown code while holding a lock.
  • Starvation: keep critical sections short; consider fair locks.
  • Livelock: add randomized backoff on retry.
  • Race conditions: use atomics, concurrent collections, immutable objects, or a lock around check-then-act sequences.

Detection: jcmd <pid> Thread.print (or jstack) prints a thread dump and reports Java-level deadlocks; ThreadMXBean.findDeadlockedThreads() does it from code.

Sources: Java Tutorial: Deadlock, Java Tutorial: Starvation and Livelock, Java Tutorial: Thread Interference, jcmd, ThreadMXBean Javadoc

Sources (0)
See inline citations in the answer above.