DeadlocksDeadlock Conditions & PreventionHard⏱️ ~2 min

Avoiding Deadlock in Common Patterns

Practical Guide
Certain code patterns are deadlock-prone. Recognize them and apply specific fixes.

Pattern: Nested Locks

Problem: Function A locks X, calls function B, which locks Y. Hidden ordering dependency.

Fix: Document lock dependencies. Ensure all paths acquire X before Y. Or restructure to avoid nesting.

Pattern: Callback While Holding Lock

Problem: Hold lock, call listener/callback. Callback tries to acquire locks, possibly your lock.

Fix: Collect data while holding lock, release lock, then call callbacks. Never call external code while holding locks.

Pattern: Lock Scope Creep

Problem: Lock acquired at start of long function, released at end. Scope grows over time as code is added.

Fix: Minimize lock scope. Acquire late, release early. Use helper methods with clear lock boundaries.

Safe Callback Pattern
Dangerouslock()listener.notify()unlock()Safelock(); data = copy(); unlock()// lock releasedlistener.notify(data)

Pattern: Dining Philosophers Style

Problem: Multiple resources, each thread needs multiple, circular dependency possible.

Fix: Global ordering of resources. Or limit concurrent attempts (N-1 philosophers). Or use a single global lock (reduces concurrency).

Golden Rule: Never call external code while holding a lock. Never acquire locks in inconsistent orders. Minimize lock scope. These three rules prevent most deadlocks.
💡 Key Takeaways
Nested locks: document dependencies, enforce consistent ordering across all call paths.
Callbacks while locked: copy data, release lock, then invoke callbacks. Never call external code while locked.
Lock scope creep: keep lock scope minimal. Acquire late, release early. Refactor long critical sections.
Dining philosophers: use global ordering, limit concurrent access, or serialize with single lock.
Three rules: no external calls while locked, consistent lock order, minimal lock scope.
📌 Examples
1Callback fix: List<Listener> copy; synchronized(lock) { copy = new ArrayList<>(listeners); } for (l : copy) l.notify();
2Scope reduction: synchronized(lock) { value = map.get(key); } process(value); // process outside lock
3Dining philosophers: footman semaphore allows only 4 of 5 philosophers to try eating. Guarantees one fork free.
← Back to Deadlock Conditions & Prevention Overview