Learn to create a deadlock in Java programmatically, with an example. Also, learn to detect deadlock and how to solve a deadlock situation in source code.
Generally, if the program is not synchronized properly and system resources are shared among threads, there is always a chance of a deadlock situation, where multiple threads are waiting to access resources held by each other.
1. Simulating a Deadlock
In Java, a deadlock is a situation where a minimum of two threads are holding the lock on some different resource, and both are waiting for the other’s resource to complete its task. And, none is able to leave the lock on the resource it is holding.
In the above case, Thread-1
has A
but need B
to complete processing and similarly Thread-2
has resource B
but need A
first.
public class ResolveDeadLockTest {
public static void main(String[] args) {
ResolveDeadLockTest test = new ResolveDeadLockTest();
final A a = test.new A();
final B b = test.new B();
// Thread-1
Runnable block1 = new Runnable() {
public void run() {
synchronized (a) {
try {
// Adding delay so that both threads can start trying to
// lock resources
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Thread-1 have A but need B also
synchronized (b) {
System.out.println("In block 1");
}
}
}
};
// Thread-2
Runnable block2 = new Runnable() {
public void run() {
synchronized (b) {
// Thread-2 have B but need A also
synchronized (a) {
System.out.println("In block 2");
}
}
}
};
new Thread(block1).start();
new Thread(block2).start();
}
// Resource A
private class A {
private int i = 10;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
// Resource B
private class B {
private int i = 20;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
}
Running the above code will result in a deadlock for very obvious reasons (explained above). Now we have to solve this issue.
2. How to Solve a Deadlock?
I believe that the solution to any problem lies in identifying the root of the problem. In our case, it is the pattern of accessing the resources A
and B
, is main issue. So, to solve it, we will simply re-order the statements where the code is accessing shared resources.
// Thread-1
Runnable block1 = 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 A but need B also
synchronized (a) {
System.out.println("In block 1");
}
}
}
};
// Thread-2
Runnable block2 = new Runnable() {
public void run() {
synchronized (b) {
// Thread-2 have B but need A also
synchronized (a) {
System.out.println("In block 2");
}
}
}
};
Run again above class, and you will not see any deadlock kind of situation. I hope it will help you avoid deadlocks and, if encountered, resolve them.
Happy Learning !!
Great explanation but 100% deadlock here is still NOT guaranteed as in case where thread-1 completes its run() calling before thread-0 initiates its call to its run(). Its all depend on CPU scheduler.
Hi Lokesh,
Great Explanation!
Can we achieve dead lock using Class Level Locking instead of using object level locking?
Great Explain :) Simple but valuable
Hi,
I have a project about make deadlock and solve it.But i do not know about what should i do for my projects.
please help me.
Hey Lokesh,
What if the resources that are locked are passed as parameters by threads , that is a & b are passed as parameters and one thread passes x & y to a, b and the other passes y & x. Can you talk about that scenario if possible. Thanks.
In such scenario, you can use any type of ordering on a and b e.g. Object.identityHashCode() can be used to compare any type of object and based on that comparison you can decide the lock order.
Greate job, thanks
Basic Factors for Deadlock
1) Mutual Exclusion
2) Hold and Wait
3) No Preemption
4) Circular Wait
Thanks for this article.
I had to design “Resource Manager” application for a multi-user system. This Resource Manager should monitor the requests made by the users (or processes) on resources of the system.
i got some basic idea through this article.
Hello!
Why have you made resourses as internal classes? I tryed to create two Integer-reference objects and they do the same work perfectly. In my opinion, example without these internal classes looks clearer. Do you have some special meaning for this solution?
In any case, thank you for good explanations!
Nothing special. I was just being lazy.
Nice example. Thanks for sharing.
hi LOKESH,
can i do the deadlock by using synchronized methods(not synchronized blocks).
Hi Lokesh,
i m getting same output in both case please do need fully.
It’s not the output that matters, it’s deadlock concept in discussion. Output may/or may not differ, both are perfectly fine.
Loved your approach of getting to the root problem by first understanding the pattern. Youd rocked it!