This example demonstrates a classic deadlock scenario in Java multithreading, where two threads end up waiting for resources that are held by each other, resulting in a permanent blockage.
A deadlock occurs when two or more threads are blocked forever, waiting for each other to release resources that they need. In this example, we demonstrate this using two threads and two locks.
The example uses:
- Two static final Object instances (
lock1
andlock2
) used as locks - Two threads (
t1
andt2
) that attempt to acquire these locks in different orders
- Acquires
lock1
- Sleeps for 1 second
- Attempts to acquire
lock2
(while still holdinglock1
)
- Acquires
lock2
- Sleeps for 1 second
- Attempts to acquire
lock1
(while still holdinglock2
)
Thread t1: lock1 → sleep → lock2
Thread t2: lock2 → sleep → lock1
The deadlock occurs because:
- Thread 1 holds
lock1
and waits forlock2
- Thread 2 holds
lock2
and waits forlock1
- Neither thread releases its lock before trying to acquire the other lock
- Both threads end up waiting for each other indefinitely
java DeadlockExample.DeadlockExample
Thread 1 is holding lock 1...
Thread 2 is holding lock 2...
Waiting for lock2 to be released
Waiting for lock1 to be released
[Program hangs due to deadlock]
To prevent deadlocks in real applications, consider these strategies:
- Lock Ordering: Always acquire locks in a consistent order
- Lock Timeouts: Use
tryLock()
with timeouts - Deadlock Detection: Implement deadlock detection mechanisms
- Resource Hierarchy: Establish a hierarchy for resource allocation
- Understanding how deadlocks occur in multithreaded applications
- Importance of proper lock ordering
- Effects of thread synchronization
- How to identify potential deadlock scenarios
This example is for educational purposes and demonstrates what to avoid in production code.