Interview Prep Zoneby CuriouserLabs

Question 4 of 5 · senior level

Compare synchronized, ReentrantLock and ReadWriteLock. How do you decide which to use, and how do you avoid deadlock?

🎤 Say this first

Default to synchronized — it's simpler, JIT-optimized (biased/thin locks historically, lock elision), impossible to forget to unlock, and visible to tooling. Reach for ReentrantLock when you need something it can't do: tryLock with timeout, interruptible acquisition, fairness, or multiple Conditions. ReadWriteLock helps only with read-heavy workloads and long critical sections — under short sections StampedLock or plain sync is often faster. Deadlock avoidance is design: global lock ordering, timeouts, and shrinking critical sections.

The full picture

CapabilitysynchronizedReentrantLockReadWriteLock
Auto-release on exception✅ always❌ needs finally❌ needs finally
Try / timed / interruptible acquire
Fairness option✅ (throughput cost)
Multiple wait-setsone (wait/notify)✅ many Conditions
Concurrent readers✅ read lock shared
ReentrantLock done right
private final ReentrantLock lock = new ReentrantLock();

void transfer(Account from, Account to, long amount) throws TimeoutException {
    if (!lock.tryLock(2, TimeUnit.SECONDS))       // deadlock-resistant
        throw new TimeoutException("busy, try later");
    try {
        // critical section
    } finally {
        lock.unlock();                            // NEVER forget
    }
}

Deadlock needs four conditions (mutual exclusion, hold-and-wait, no preemption, circular wait); you only have to break one. In practice: acquire locks in one global order (e.g., lock accounts by ascending id), keep critical sections tiny, never call foreign/user code while holding a lock, and prefer tryLock with timeout at integration boundaries. Detect with jstack (it prints found deadlocks) or ThreadMXBean.findDeadlockedThreads().

🔄 Likely follow-up questions

  • What is lock coarsening / lock elision by the JIT?
  • When would StampedLock's optimistic read beat a ReadWriteLock?
  • How do you find which lock a production app is contending on? (JFR lock profiling)