why does this code produce deadlock? [duplicate]

我与影子孤独终老i 提交于 2020-01-22 17:50:06

问题


class A {
    static final int i;
    static {
        i = 128;

        Thread t = new Thread() {
            public void run() {
                System.out.println("i=" + i);
            }
        };
        t.start();
        try {
           t.join();
        } catch (InterruptedException e) {
           Thread.currentThread().interrupt();
        }
    }
}
public class MainTesting {


    public static void main(String[] args) {
        A a = new A();
        System.out.println("finish");
    }
}

I never get finish get printed and value of i. Why is it so?


回答1:


You start off on thread 1 (the "main" thread), and start executing the static initializer for the A class.

Within that static initializer, you then start a new thread (2), which uses something within the A class. That means that thread 2 needs to wait until the A class has finished initilaizing before it will proceed, as per section 12.4.2 of the JLS:

If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this step.

However, your static initializer for A waits until thread 2 has completed (by calling join()) before it completes, leading to deadlock: the static initializer can't complete until thread 2 has completed, and thread 2 can't complete until the static initializer has completed...

Upshot: don't do this :)




回答2:


Loading of classes and static blocks are implicitly synchronized This means you cannot access anything in a class in another thread while it is being initialised. In this case the initialisation is waiting for a thread which is using A.i. In other words, it is waiting for the first thread to finish the static block.

Note: it doesn't use a normal lock and the thread claims to be in a Runnable state even though it is deadlocked.

2013-06-21 11:20:40
Full thread dump Java HotSpot(TM) 64-Bit Server VM (23.21-b01 mixed mode):

"Thread-0" prio=6 tid=0x000000000d55d000 nid=0x3cc4 in Object.wait() [0x000000000dbdf000]
   java.lang.Thread.State: RUNNABLE
    at Main$1.run(Main.java:14) <- where A.i is referenced.

"main" prio=6 tid=0x00000000022df000 nid=0x3284 in Object.wait() [0x000000000257e000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007d5610448> (a Main$1)
    at java.lang.Thread.join(Thread.java:1258)
    - locked <0x00000007d5610448> (a Main$1)
    at java.lang.Thread.join(Thread.java:1332)
    at Main.<clinit>(Main.java:19)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:188)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:113)


来源:https://stackoverflow.com/questions/17236561/why-does-this-code-produce-deadlock

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!