+-

我的代码中遇到了死锁情况.我使用以下测试代码重现了该场景(也请查看行号注释).
我有一个ExecuterService,它接受3个任务,2个任务在同一个对象上有一个同步块,没有初始化它应该有空值.
java中不允许synchronized(null){}所以我期待第2行出错.但是,这是以死锁执行的.即前三个任务在第三个任务中等待. (见输出-1)
现在,如果我将第1行更改为Object lock = new Object();代码将完美运行,没有任何死锁(Output-2).我只是想知道当我们提供未初始化的互斥对象时JVM到底发生了什么?看起来JVM正在为它创建一个静态副本,它由所有任务共享.因此陷入僵局
public class Test {
Object lock; //line -1
Integer a = 10;
public static void main(String[] arg) {
new Test().doIt();
}
public void doIt() {
ExecutorService service = Executors.newFixedThreadPool(3);
service.submit(new Runnable() {
public void run() {
synchronized (Test.this.lock) { //line -2
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Test.this.a = (int) Thread.currentThread().getId();
System.out.println(a + " " + Thread.currentThread().getId());
}
}
});
service.submit(new Runnable() {
public void run() {
synchronized (Test.this.lock) {
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Test.this.a = (int) Thread.currentThread().getId();
System.out.println(a + " " + Thread.currentThread().getId());
}
}
}
);
service.submit(new Runnable() {
public void run() {
Test.this.a = (int) Thread.currentThread().getId();
while (true) {
try {
Thread.sleep(1 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(a + " Main");
}
}
});
}
}
输出-1
11 Main
11 Main
11 Main
11 Main
11 Main
11 Main
11 Main
11 Main
11 Main
11 Main
11 Main
.
.
.
输出-2
11 Main
11 Main
11 Main
11 Main
9 9
9 Main
9 Main
9 Main
9 Main
9 Main
10 10
10 Main
10 Main
.
.
.
最佳答案
你没有死锁 – 就像你预期的那样有一个错误.第一个和第二个任务将抛出NullPointerException,只剩下第三个任务在运行.
如果在try / catch语句中包围run()的主体,则可以看到这一点.
点击查看更多相关文章
转载注明原文:Java:当lock为null时,为什么这是一个死锁? - 乐贴网