什么线程正在初始化静态字段和静态块?根据我的实验,我得出结论,它与“调用”线程相同,即
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]
是否有任何限制,或者总是如此?
答案 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]将不会触及它们。静态初始化完成一次。