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...");
}
}
}
}
}
在上面的程序中,两个线程都在休眠10毫秒。所以一旦时间到期,demo1就可以锁定lock1上的lock2和demo2。但事实并非如此。他们陷入僵局。
有人可以解释原因吗?
提前致谢。
答案 0 :(得分:0)
我们将忽略这里的设计问题,并假设您只是试图通过玩具示例来理解线程。
问题是你的锁定范围。我们在这里列出操作顺序:
在ThreadDemo1
:
Lock1
Lock2
Lock2
Lock1
同样,在ThreadDemo2
:
Lock2
Lock1
Lock1
Lock2
从这里的操作顺序可以看出,在释放初始锁定之前,两个ThreadDemo
类都尝试获取另一个锁。这基本上保证了死锁,因为它们将永远停留在等待对方释放其初始锁定。
你真正想要发生的是ThreadDemo1
:
Lock1
Lock1
Lock2
Lock2
这是ThreadDemo2
:
Lock2
Lock2
Lock1
Lock1
要做到这一点,只需更改:
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...");
}
} // <----- We're going to move this bracket
}
}
对此:
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) {
}
} // <----- We moved it here
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
在ThreadDemo2
班级中进行相同的更改