Sex*_*ast 8 java concurrency multithreading deadlock
我是多线程的新手,我遇到了这个例子:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.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...");
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这会导致以下示例输出:
Thread 1: Holding lock 1...
Thread 2: Holding lock 2...
Thread 1: Waiting for lock 2...
Thread 2: Waiting for lock 1...
Run Code Online (Sandbox Code Playgroud)
即,存在僵局.但是,如果我们改变在第二个线程中获得的锁的顺序,那么它现在看起来像这样:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.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 (Lock1) {
System.out.println("Thread 2: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作,示例输出如下所示:
Thread 1: Holding lock 1...
Thread 1: Waiting for lock 2...
Thread 1: Holding lock 1 & 2...
Thread 2: Holding lock 1...
Thread 2: Waiting for lock 2...
Thread 2: Holding lock 1 & 2...
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释第一个导致死锁的情况,以及为什么第二个代码的更改会修复它?
这是第一种情况的可能情景:
线程1获取Lock1并进入休眠状态10毫秒.现在线程2获取Lock2并进入睡眠状态10毫秒.
现在,线程1尝试获取Lock2,但是由于它被线程2 获取而无法获取它,而线程2试图获取Lock1由线程1锁定的线程.
在第二种情况下,让我们假设第一个线程被选中运行.它得到了Lock1,而另一个线程被阻止,因为它也试图获得Lock1.现在,线程1进入休眠状态,然后进入第二个(嵌套的)同步块.它试图得到它(因为它仍然是免费的) - 现在他得到了2个锁.另一个线程仍然被阻止.
只有在它完成执行后,它才会释放两个锁(因为它退出synchronized块),现在JVM可以自由决定选择哪个线程,但实际上并不重要,同样的逻辑也会发生.
| 归档时间: |
|
| 查看次数: |
126 次 |
| 最近记录: |