0% found this document useful (0 votes)
3 views

3

Deadlock in Java occurs when two or more threads are waiting for each other to release locks, preventing any of them from proceeding. The conditions for deadlock include mutual exclusion, hold and wait, no preemption, and circular wait. To prevent deadlocks, developers should avoid nested locks, unnecessary locks, and utilize thread joins with time limits.

Uploaded by

gvnbca
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

3

Deadlock in Java occurs when two or more threads are waiting for each other to release locks, preventing any of them from proceeding. The conditions for deadlock include mutual exclusion, hold and wait, no preemption, and circular wait. To prevent deadlocks, developers should avoid nested locks, unnecessary locks, and utilize thread joins with time limits.

Uploaded by

gvnbca
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Deadlock in Java Multithreading with Examples

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.

Conditions for 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 of Deadlock in Java

Example

// Java Program to understand Deadlock


public class Main {
public static void main(String[] args) {
final String resource1 = "foo";
final String resource2 = "bar";
// t1 tries to lock resource1 then resource2
Thread t1 = new Thread() {
public void run() {
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1"); // first print statement
try { Thread.sleep(100);} catch (Exception e) {}
synchronized (resource2) {
System.out.println("Thread 1: locked resource 2"); // second print statement
}
}
}
};
// t2 tries to lock resource2 then resource1
Thread t2 = new Thread() {
public void run() {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2"); // third print statement
try { Thread.sleep(100);} catch (Exception e) {}
synchronized (resource1) {
System.out.println("Thread 2: locked resource 1"); // fourth print statement
}
}
}
};
t1.start();
t2.start();
}
}
Output:

Thread 1: locked resource 1

Thread 2: locked resource 2

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.

More Complicated Deadlocks

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:

Thread 1 locks A, waits for B


Thread 2 locks B, waits for C
Thread 3 locks C, waits for D
Thread 4 locks D, waits for A
Thread 1 waits for thread 2, thread 2 waits for thread 3, thread 3 waits for thread 4, and thread 4
waits for thread 1.
Deadlocks Detection

Observe the following steps for the detection of deadlocks.

Step 1: Compile and execute the program using the commands javac and Java, respectively.

Here, we are executing the above-written program, which contains a deadlock.

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.

We can see that the Main has the process ID 8680.


Step 3: Type the following command in the command prompt and run

1. jcmd <PID> Thread.print

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

//Java Program to avoid deadlock


public class Main {
public static void main(String ar[]) {
Main test = new Main();
final resource1 a = test.new resource1();
final resource2 b = test.new resource2();
// Thread - 1
Runnable t1 = new Runnable() {
public void run() {
synchronized (b) {
try {
/* Adding delay so that both threads can start trying to lock resources */
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Thread - 1 have resource2 but need resource1 also
synchronized (a) {
System.out.println("In block 1");
}
}
}
};
// Thread - 2
Runnable t2 = new Runnable() {
public void run() {
synchronized (b) {
// Thread - 2 have resource2 but need resource1 also
synchronized (a) {
System.out.println("In block 2");
}
}
}
};
new Thread(b1).start(); // first thread
new Thread(b2).start(); // second thread
}
// resource1
private class resource1 {
private int i = 10;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
// resource2
private class resource2 {
private int i = 20;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
}
Output:

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.

How to avoid deadlocks in Java?

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.

Important Points to Remember

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.

You might also like