All 15 Concurrency & Threads questions
More in Concurrency & Threads
Advertisement
Back to results for “Error Handling”
Java › Concurrency & Threads

What causes a deadlock in multithreaded Java code, and what is the classic "lock ordering" strategy for preventing it?

Intermediate

Answer

A deadlock occurs when two or more threads each hold a lock the other needs while waiting to acquire the lock the other already holds, creating a circular wait with no thread able to proceed -- the classic prevention strategy is establishing and consistently following a global, agreed-upon lock acquisition order across all code paths (e.g., always acquiring lock A before lock B, never the reverse, regardless of which method or code path is involved), eliminating the possibility of circular waiting entirely since a consistent order can never form a cycle.
// DEADLOCK RISK: inconsistent lock ordering across two methods
public void transferAtoB() {
    synchronized (lockA) {
        synchronized (lockB) { /* transfer */ }
    }
}
public void transferBtoA() {
    synchronized (lockB) {  // acquires in OPPOSITE order -- deadlock risk if called concurrently!
        synchronized (lockA) { /* transfer */ }
    }
}

// FIX: always acquire in the same consistent global order (e.g., by object identity hash)
// regardless of the logical "direction" of the operation
Real-world example A banking application's fund transfer logic experiences an intermittent production deadlock traced to two methods acquiring the same pair of account locks in opposite order depending on transfer direction, fixed by establishing a consistent lock-ordering rule (e.g., always locking the account with the lower account ID first) regardless of transfer direction.

Common follow-ups: What other deadlock prevention strategies exist besides consistent lock ordering (like tryLock with timeout)?;How would you use a thread dump to diagnose an actual deadlock occurring in a running production application?