public class DeadlockDemo2 {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadDemo1 demo1 = new ThreadDemo1();
ThreadDemo2 demo2 = new ThreadDemo2();
demo1.start();
demo2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
In above program, both Threads are sleeping for 10 milliseconds. So once the time expires, demo1 can acquire lock on lock2 and demo2 on lock1. But It does not happen so. They go under deadlock.
Can somebody explain the reason?
Thanks in advance.
We'll ignore the design issues here and assume you're just trying to understand threading with a toy example.
The problem is your lock scoping. Let's list out the order of operations here:
In
ThreadDemo1:Lock1Lock2Lock2Lock1Similarly, in
ThreadDemo2:Lock2Lock1Lock1Lock2As you can see from the order of operations here, both of your
ThreadDemoclasses attempt to acquire the other lock before freeing their initial lock. This basically guarantees deadlock as they will be stuck forever waiting for the other to release their initial lock.What you actually wanted to happen was this in
ThreadDemo1:Lock1Lock1Lock2Lock2And this in
ThreadDemo2:Lock2Lock2Lock1Lock1To do this, simply change this:
To this:
And make the same change in your
ThreadDemo2class