什么线程正在初始化静态字段?

时间:2013-10-18 08:07:17

标签: java

什么线程正在初始化静态字段和静态块?根据我的实验,我得出结论,它与“调用”线程相同,即

class Foo {
    static {
        System.err.printf("static {}:   %s\n", Thread.currentThread());
    }
}

public class Mini_StaticInitialization {
    public static void main(final String[] args) {
        System.err.printf("main:        %s\n", Thread.currentThread());
        new Foo();
    }
}

输出

main:        Thread[main,5,main]
static {}:   Thread[main,5,main]

是否有任何限制,或者总是如此?

4 个答案:

答案 0 :(得分:6)

通常静态字段在首次初始化类的线程中初始化,但我不认为这是在JLS中指定的。

那个通常也是加载类的相同线程,但不一定。

JLS最相关的部分可能是12.4.2. Detailed Initialization Procedure

  

由于Java编程语言是多线程的,因此初始化类或接口需要仔细同步,因为其他一些线程可能正在尝试同时初始化相同的类或接口。

暗示(但不声明或要求)初始化发生在导致该类需要初始化的线程中。

答案 1 :(得分:2)

加载类时运行静态块。我会假设这始终是导致类加载的线程。如果以某种方式引用类,这可能是一个不同的线程,即使您没有创建Foo的实例。

答案 2 :(得分:0)

静态块中的代码在类加载时执行,并且只执行一次,无论您创建的类的实例数是多少。在您的程序主线程中,调用线程和您的程序在同一个线程中运行。如果您尝试在另一个线程中执行新的Foo(),您将看到与仅在调用线程中发生静态初始化相同的输出。

答案 3 :(得分:0)

首先加载的线程Foo将初始化静态字段/运行静态块。如果Foo已被另一个线程加载,则Thread [main,5,main]将不会触及它们。静态初始化完成一次。