Deadlocks • Deadlock Conditions & PreventionHard⏱️ ~2 min
Breaking Hold-and-Wait
Alternative Strategy
Breaking hold-and-wait means threads cannot hold resources while waiting for more. Either get everything at once, or hold nothing.
Approach 1: All-or-Nothing
Request all needed locks atomically. If any lock is unavailable, release all and retry. No thread ever holds some locks while waiting for others.
Approach 2: Two-Phase Locking
Phase 1: Acquire all locks (growing phase). Phase 2: Release all locks (shrinking phase). Once you start releasing, you cannot acquire more. Used in databases.
All-or-Nothing Pattern
The Drawbacks
Reduced concurrency: Holding all locks longer than needed. Others wait even if they need only one.
Starvation risk: Thread keeps failing to get all locks, retries forever while others succeed.
Must know all locks upfront: Sometimes you do not know what you need until partway through.
When to Use: Works well when lock sets are small and known in advance. Impractical for dynamic or large lock sets. Lock ordering is usually preferred.
💡 Key Takeaways
✓All-or-nothing: acquire all locks atomically, or none. Release and retry if any unavailable.
✓Two-phase locking: growing phase (acquire), then shrinking phase (release). No mixing.
✓Eliminates hold-and-wait: thread never holds a lock while waiting for another.
✓Drawback: reduced concurrency, holding locks longer than needed. Possible starvation.
✓Requires knowing all locks upfront. Not always practical for dynamic scenarios.
📌 Examples
1All-or-nothing: tryLock(A), tryLock(B). If B fails, unlock(A), sleep, retry both.
2Database 2PL: transaction acquires row locks during query, releases all at commit. Strict ordering.
3Resource allocator: request (CPU, memory, disk) as a batch. If any unavailable, wait without holding others.