为什么这段代码会产生死锁?

Sun*_*nny 11 java multithreading

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

我永远不会得到finish印刷和我的价值.为什么会这样?

Jon*_*eet 13

从线程1("主"线程)开始,然后开始为A类执行静态初始化程序.

在该静态初始化程序中,然后启动一个新线程(2),该线程使用A类中的某些内容.这意味着线程2需要等到A类完成初始化才能继续进行,如JLS第12.4.2节所述:

如果C的Class对象指示某个其他线程正在为C进行初始化,则释放LC并阻止当前线程,直到通知正在进行的初始化已完成,此时重复此步骤.

然而,你的静态初始化A等待,直到线程2完成(通过调用join())之前完成,从而导致死锁:静态初始化无法完成,直到线程2已完成,并且线程2无法完成,直到静态初始化已完成...

Upshot:不要这样做:)

  • 请不要介意,但我想你已经在http://stackoverflow.com/questions/6686333/deadlock-caused-by-thread-join-in-a-static-block中回答了这个问题. (2认同)

Pet*_*rey 6

隐式同步加载类和静态块这意味着在初始化时,您无法访问另一个线程中的类中的任何内容.在这种情况下,初始化正在等待正在使用的线程A.i.换句话说,它正在等待第一个线程完成静态块.

注意:它不使用普通锁,并且线程声称处于Runnable状态,即使它已死锁.

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)
Run Code Online (Sandbox Code Playgroud)