3

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

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

4 回答 4

6

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

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

JLS 最相关的部分可能是12.4.2。详细的初始化程序

因为 Java 编程语言是多线程的,所以类或接口的初始化需要仔细同步,因为其他一些线程可能同时尝试初始化同一个类或接口。

意味着(但没有声明或要求)初始化发生在导致类需要初始化的线程中。

于 2013-10-18T08:11:09.763 回答
2

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

于 2013-10-18T08:10:50.483 回答
0

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

于 2013-10-18T09:13:58.763 回答
0

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

于 2013-10-18T08:14:35.047 回答