Fundamentals 9 min read

How to Break Java’s Deadlock: From Coffman Conditions to Practical Lock Strategies

This article explains why naive synchronized locks can cause deadlocks in Java, introduces the four Coffman conditions, and presents three practical solutions—acquiring all resources at once, using explicit locks with wait/notify, and ordering lock acquisition—to prevent deadlock in concurrent applications.

Programmer DD
Programmer DD
Programmer DD
How to Break Java’s Deadlock: From Coffman Conditions to Practical Lock Strategies

Understanding Java Deadlock

When multiple threads use synchronized methods without careful design, they can enter a deadlock where each thread waits indefinitely for a resource held by another.

Coffman Conditions

Four conditions must hold simultaneously for a deadlock to occur: mutual exclusion, hold and wait, no preemption, and circular wait.

Java’s built‑in synchronized lock can lead to “dead waiting” because it never releases a lock voluntarily.

Solution 1: Acquire All Required Resources at Once

Introduce an AccountBookManager that grants both source and target accounts together; if both are not available, the thread retries.

class Account {
    private int balance;
    // transfer
    void transfer(Account target, int amt) {
        synchronized (this) {
            synchronized (target) {
                if (this.balance > amt) {
                    this.balance -= amt;
                    target.balance += amt;
                }
            }
        }
    }
}

Improved version with manager:

class AccountBookManager {
    synchronized boolean getAllRequiredAccountBook(Object from, Object to) {
        // return true only when both books are obtained
    }
    synchronized void releaseObtainedAccountBook(Object from, Object to) { /* ... */ }
}
class Account {
    private AccountBookManager manager;
    void transfer(Account target, int amt) {
        while (!manager.getAllRequiredAccountBook(this, target)) {
            return;
        }
        try {
            synchronized (this) {
                synchronized (target) {
                    if (this.balance > amt) {
                        this.balance -= amt;
                        target.balance += amt;
                    }
                }
            }
        } finally {
            manager.releaseObtainedAccountBook(this, target);
        }
    }
}

Solution 2: Break Hold‑and‑Wait

Use explicit locks (java.util.concurrent.locks.Lock) with tryLock, wait/notify, or timeout to avoid indefinite waiting.

Solution 3: Impose a Global Lock Ordering

Assign a unique identifier to each account and always lock the lower‑id account first, eliminating circular wait.

class Account {
    private int id;
    private int balance;
    void transfer(Account target, int amt) {
        Account smaller = this.id < target.id ? this : target;
        Account larger  = this.id < target.id ? target : this;
        synchronized (smaller) {
            synchronized (larger) {
                if (this.balance > amt) {
                    this.balance -= amt;
                    target.balance += amt;
                }
            }
        }
    }
}

In real systems, database transactions, optimistic locking, or distributed locks (e.g., Redis) can also prevent deadlocks.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

concurrencydeadlockSynchronizationLockscoffman-conditions
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.