3
3
Deadlock in Java is a part of multithreading. Deadlock can occur in a situation when a thread is
waiting for an object lock that is acquired by another thread, and a second thread is waiting for an
object lock that is acquired by the first thread. Since both threads are waiting for each other to
release the lock, the condition is called a deadlock.
1. Mutual Exclusion: At least one resource must be held in a non-shareable mode. In other
words, only one process can use the resource at any given time.
2. Hold and Wait: A process holding at least one resource is waiting to acquire additional
resources that are currently held by other processes.
3. No Preemption: Resources cannot be forcibly removed from a process holding them. The
process must release the resource voluntarily.
4. Circular Wait: A set of processes is waiting on each other in a circular chain, where each
process is holding a resource and waiting for the next process in the chain to release another
resource.
Here, note that if even one of these conditions is not present, a deadlock cannot occur.
Example
Explanation
There are two resources: resource1 and resource2. First thread t1 locks the resource1 and sleeps.
Similarly, the second thread, t2, locks resource2 and sleeps. Each thread sleeps for 100 milliseconds.
After that, the first thread, t1, tries to acquire resource2, and the second thread, t2, tries to acquire
resource1. However, resource1 is acquired by thread t1, and resource2 is acquired by thread t2,
resulting in a deadlock situation, and the same is evident from the output. The second and fourth
print statements do not execute.
A deadlock may also include more than two threads. The reason is that it can be difficult to detect a
deadlock. Here is an example in which four threads have deadlocked:
Step 1: Compile and execute the program using the commands javac and Java, respectively.
Step 2: Open another command prompt window and run the command jps -l
The command jps -l lists all the processes (with process ID) of Java that are running.
Replace <PID> with the process ID 8680 and observe the output.
Output:
8680:
2025-04-03 13:46:30
Full thread dump Java HotSpot(TM) 64-Bit Server VM (12.0.2+10 mixed mode, sharing):
Preventing Deadlock
A solution for a problem is found at its roots. In a deadlock, the pattern of accessing resources A and
B is the main issue. To solve the issue, we will have to simply re-order the statements where the
code is accessing shared resources.
Example
In block 1
In block 2
Explanation
In the above program, there are two threads, t1 and t2. After both the threads are spawned, thread
t1 acquires resource b and sleeps for 100 milliseconds. Meanwhile, thread t2 also tries to acquire
resource b, and since it is already acquired by thread t1, thread t2 waits.
After that, thread t1 wakes from sleep, applies a lock on resource a, and then finishes its execution.
Thus, releasing both resources, a and b. Thread t2 now acquires resource b and then resource a and
does its job. Note that both threads do their task. Hence, there is no deadlock.
Deadlocks cannot be completely resolved. But we can avoid them by following the basic rules as
given below:
1. Avoid Nested Locks: We must avoid giving locks to multiple threads; this is the main reason
for a deadlock condition. It normally happens when you provide locks for various threads.
2. Avoid Unnecessary Locks: The locks should be given to the important threads. Giving locks
to the unnecessary threads that cause the deadlock condition.
3. Using Thread Join: A deadlock usually happens when one thread is waiting for the other to
finish. In this case, we can use join with the maximum time that a thread will take.
1. If multiple threads use synchronized blocks or methods to access shared resources, they can
create a deadlock situation.
2. Improper usage of locks may lead to deadlocks.
3. Minimize the use of nested synchronized blocks. It reduces the chances of a deadlock.
4. Use timeouts with locks to avoid indefinite waiting.
5. Tools like VisualVM or jConsole can help detect deadlocks during runtime.
6. Deadlocks cannot be resolved automatically. Developers need to either avoid situations
leading to deadlock or use techniques like lock hierarchy to ensure threads acquire locks in a
specific order.