哪个线程初始化静态字段?

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]

这是否有任何限制,还是总是这种情况?

1
你的应用程序是单线程的。它的执行都在同一个单一线程中进行。那么你说的“什么线程……?”是什么意思呢?上面显示的应用程序只有一个线程。 - scottb
出于好奇,你为什么关心哪个线程执行静态块? - Joachim Sauer
@scottb 这是一个测试用例,目的是为了制定我的问题,显然这不是我的应用程序。 - Micha Wiedenmann
4个回答

6
通常情况下,静态字段在首次初始化类的线程中初始化,但我认为JLS没有明确规定。通常这也是加载类的同一线程,但不一定如此。JLS最相关的部分可能是12.4.2.详细初始化过程:由于Java编程语言是多线程的,因此类或接口的初始化需要仔细同步,因为某些其他线程可能正在尝试同时初始化相同的类或接口。这意味着(但并未声明或要求)初始化发生在导致类需要初始化的线程中。

2
静态代码块会在类加载时运行。我认为这通常是导致类加载的线程。但如果以某种方式引用了类,即使不创建Foo实例,可能会是另一个线程。

2
严格来说,这发生在类初始化而不是类加载时。大多数情况下,这两个事件几乎同时发生,但并非总是如此。 - Joachim Sauer

0

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


0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接