2013-10-18 39 views
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

+0

出于好奇:你为什么会关心哪个线程执行静态块? –

+0

@scottb这是一个测试用例来阐明我的问题,显然这不是我的应用程序。 –

回答

6

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

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

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

因为Java编程语言是多线程的,一类或接口的初始化阶段需要仔细同步,因为一些其他线程试图初始化同类或接口。

这意味着(但不说明或要求)在初始化发生在导致类需要初始化线程。

2

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

+2

严格地说,这发生在类初始化上,而不是类加载上。大多数情况下,这两者几乎同时发生,但并非总是如此。 –

0

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

0

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