Thread Deadlock is a situation which can occur in any Java application which has multiple threads .In this section we are discussing the concept of thread deadlock in java with suitable example.
Thread deadlock in java
Deadlock is a situation , when two or more threads are waiting each other and hence blocked forever.Our application freezes in such a situation . If our application is a GUI based application , then the GUI will freeze . The deadlock situation can be well understood with the help of any profiler. By inspecting the heap dump , it is possible to identify which all threads are locked each other.(If we are using newer versions of JDK , then the JDK/bin contains the JVisualVM.exe. It is the inbuilt profiler within the JDK. Just open the profiler and profile our application which is suspecting for thread deadlock. Then click on the heap dump option)
Thread deadlock in Java example
Let us see this with an example.
We have two threads .One thread for printing even numbers and the other for printing odd numbers.Also we have two shared objects .
First thread is:
public class EvenThread extends Thread {
private Object sharedFirst = null;
private Object sharedSecond = null;
public EvenThread(String name, Object sharedFirst, Object sharedSecond) {
super(name);
this.sharedFirst = sharedFirst;
this.sharedSecond = sharedSecond;
}
public void run() {
synchronized (sharedFirst) {
System.out.println("Thread " + getName() + " acquired lock on sharedFirst");
synchronized (sharedSecond) {
System.out.println("Thread " + getName() + " acquired lock on sharedSecond");
int num = 0;
while (num <= 100) {
System.out.println("Even number = " + num);
num = num + 2;
}
}
}
}
}
Now the second thread is:
public class OddThread extends Thread {
private Object sharedFirst = null;
private Object sharedSecond = null;
public OddThread(String name, Object sharedFirst, Object sharedSecond) {
super(name);
this.sharedFirst = sharedFirst;
this.sharedSecond = sharedSecond;
}
public void run() {
synchronized (sharedSecond) {
System.out.println("Thread " + getName() + " acquired lock on sharedSecond");
synchronized (sharedFirst) {
System.out.println("Thread " + getName() + " acquired lock on sharedFirst");
int num = 1;
while (num <= 100) {
System.out.println("Odd number = " + num);
num = num + 2;
}
}
}
}
}
Now let us see the main to run the above threads,
public class DeadLockMain {
public DeadLockMain(){
}
public static void main(String[]args){
Object sharedFirst = new Object();
Object sharedSecond = new Object();
EvenThread evenThread = new EvenThread("Even",sharedFirst,sharedSecond);
OddThread oddThread = new OddThread("Odd",sharedFirst,sharedSecond);
evenThread.start();
oddThread.start();
}
}
The deadlock scenario is explained below.
1)EvenThread acquires lock on sharedFirst.
2)OddThread acquires lock on sharedSecond.
3) EvenThread is trying to acquire lock on sharedSecond which is locked for OddThread.So EvenThread is waiting for OddThread .(Second synchronized block of run() method in EvenThread.java )
4)OddThread is trying to acquire lock on sharedFirst which is locked for EvenThread.So OddThread is waiting for EvenThread .(Second synchronized block of run() method in OddThread.java)
So both these threads are waiting each other. They will never come out of that stage. The output makes the concept a bit more clear.
Output
Thread Even acquired lock on sharedFirst
Thread Odd acquired lock on sharedSecond
Two threads executes reaches in the first synchronized block.There both the threads waiting each other.(If you take the heap dump , then the deadlock will be reported there.If we use any profiler then also it is possible to identify the deadlock.)
Resolving thread deadlock
If we have synchronized blocks inside another , then the order should be given with proper care. Care should be taken if we call a synchronized method from another synchronized method.Use synchronized keyword when it is necessary only.
See Related Discussions
The join() method in Threading
The yield() method in Threading