Two people meet in a narrow hallway. Each steps aside to let the other pass. They step the same direction. They step again. Same direction. They're stuck in an endless dance, both being polite but neither making progress.
This is livelock. It's one of three concurrency hazards that can bring your application to a halt, along with deadlock and starvation.
These problems don't crash your program. They're worse. Your program keeps running but stops making progress. Understanding these hazards is essential for writing correct concurrent code.
In this article, we'll explore:
If you're enjoying this newsletter and want to get even more value, consider becoming a [paid subscriber](https://blog.algomaster.io/subscribe).
As a paid subscriber, you'll unlock all premium articles and gain full access to all [premium courses](https://algomaster.io/newsletter/paid/resources) on [algomaster.io](https://algomaster.io).
A deadlock occurs when two or more threads are blocked forever, each waiting for a resource held by another.
Consider two threads transferring money between accounts:
Thread 1 holds Lock A and waits for Lock B. Thread 2 holds Lock B and waits for Lock A. Neither can proceed. They're deadlocked.
Deadlock can only occur when ALL four conditions hold simultaneously:
Break any one condition and deadlock becomes impossible.
Here's a complete deadlock example:
Output:
Always acquire locks in a consistent global order. This breaks the circular wait condition.
Use tryLock with timeout. If you can't get all locks, release what you have and retry.
Use a single lock for all related resources. This eliminates hold-and-wait.
Trade-off: Reduces concurrency since only one transfer can happen at a time.
Design your code to avoid acquiring multiple locks.
In Java, you can detect deadlocks using thread dumps:
The system can build a resource allocation graph and check for cycles:
If the graph has a cycle, deadlock exists.
A livelock occurs when threads are not blocked but still can't make progress because they keep responding to each other.
Unlike deadlock where threads are frozen, in livelock threads are active but stuck in an endless loop of action and reaction.
Both diners keep passing the spoon to each other, being polite. Neither ever eats.
Add randomness to break the symmetry:
Give one thread priority to break the tie:
Limit the number of retries before taking alternative action:
Starvation occurs when a thread is unable to gain access to shared resources because other threads are constantly acquiring them first.
The thread isn't deadlocked. It's just perpetually waiting while others cut in line.
The low-priority thread might never get the lock because high-priority threads keep acquiring it.
Use fair locks that serve threads in FIFO order:
Don't rely on thread priorities for correctness:
Give each thread its own resources when possible:
Ensure every thread eventually gets access:
Solution: Always update rows in the same order (by ID).
When two devices transmit simultaneously on Ethernet:
Solution: Exponential random backoff (each device waits a random time).
Solution: Use fair read-write lock: new ReentrantReadWriteLock(true).
Track wait times:
Deadlock:
Livelock:
Starvation:
Best Practices:
Thank you for reading!
If you found it valuable, hit a like and consider subscribing for more such content every week.
If you have any questions or suggestions, leave a comment.
This post is public so feel free to share it.
P.S. If you're enjoying this newsletter and want to get even more value, consider becoming a [paid subscriber](https://blog.algomaster.io/subscribe).
As a paid subscriber, you'll unlock all premium articles and gain full access to all [premium courses](https://algomaster.io/newsletter/paid/resources) on [algomaster.io](https://algomaster.io).
There are [group discounts](https://blog.algomaster.io/subscribe?group=true), [gift options](https://blog.algomaster.io/subscribe?gift=true), and [referral bonuses](https://blog.algomaster.io/leaderboard) available.
Checkout my [Youtube channel](https://www.youtube.com/@ashishps_1/videos) for more in-depth content.
Follow me on [LinkedIn](https://www.linkedin.com/in/ashishps1/) and [X](https://twitter.com/ashishps_1) to stay updated.
Checkout my [GitHub repositories](https://github.com/ashishps1) for free interview preparation resources.
I hope you have a lovely day!
See you soon, Ashish
[IMAGE 1: Deadlock Circular Wait] <!-- Two or more threads in a cycle, each holding one resource and waiting for another -->
[IMAGE 2: Four Conditions for Deadlock] <!-- Visual showing all four conditions must be present -->
[IMAGE 3: Livelock Hallway] <!-- Two people stepping side to side, never passing -->
[IMAGE 4: Starvation Queue] <!-- High priority threads cutting in line, low priority waiting forever -->
[IMAGE 5: Comparison Table] <!-- Side-by-side visual of deadlock, livelock, starvation -->
[IMAGE 6: Prevention Strategies] <!-- Mapping problems to solutions -->