+-
Java:当lock为null时,为什么这是一个死锁?
我的代码中遇到了死锁情况.我使用以下测试代码重现了该场景(也请查看行号注释).

我有一个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时,为什么这是一个死锁? - 乐贴网