Deadlocks • Deadlock Conditions & PreventionMedium⏱️ ~2 min
Lock Ordering: The Primary Prevention Strategy
Core Strategy
Lock ordering prevents deadlock by ensuring all threads acquire locks in the same global order. If everyone goes A→B→C, no cycles can form.
Why It Works
Circular wait requires Thread 1 to hold A and want B while Thread 2 holds B and wants A. With lock ordering, Thread 2 must acquire A before B. So either Thread 1 gets A first (Thread 2 waits) or Thread 2 gets A first (Thread 1 waits). No cycle possible.
Defining the Order
Assign each lock a number or use memory address. Always acquire lower-numbered locks first. Document this order. All code paths must follow it.
Lock Ordering Prevents Cycles
Practical Implementation
By object identity: Compare memory addresses. Lower address first. Works for any objects.
By hierarchy: Global locks before local. Parent before child. Database before table before row.
By name: Alphabetical order of lock names. Simple and easy to verify.
Key Rule: If you ever need both lock A and lock B, always acquire them in the same order. This must be enforced across all code paths and all developers.
💡 Key Takeaways
✓Lock ordering: define a global order, always acquire locks in that order. Prevents circular wait.
✓With consistent ordering, one thread always waits for another. No cycles can form.
✓Order by memory address, hierarchy, or naming convention. Document and enforce it.
✓All code paths must follow the same order. One violation can reintroduce deadlock.
✓This is the most practical deadlock prevention for application code.
📌 Examples
1Bank transfer: Always lock account with lower ID first. transfer(A,B) and transfer(B,A) both lock min(A,B) first.
2Hierarchy order: Lock database connection before table lock before row lock. Never reverse.
3Address order: if (addr(lockA) < addr(lockB)) { lock(A); lock(B); } else { lock(B); lock(A); }