【发布时间】:2011-01-07 07:41:29
【问题描述】:
在我的应用程序中,有一个如下所示的类:
public class Client {
public synchronized static print() {
System.out.println("hello");
}
static {
doSomething(); // which will take some time to complete
}
}
该类将用于多线程环境,多个线程可能同时调用Client.print()方法。不知道thread-1有没有机会触发类初始化,在类初始化完成之前thread-2进入print方法打印出“hello”字符串?
我在生产系统(64 位 JVM + Windows 2008R2)中看到了这种行为,但是,我无法在任何环境中用简单的程序重现这种行为。
在 Java 语言规范第 12.4.1 节 (http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html) 中,它说:
类或接口类型 T 将在以下任何一项第一次出现之前立即初始化:
- T 是一个类,并创建了一个 T 的实例。
- T 是一个类,调用了 T 声明的静态方法。
- 分配了一个由 T 声明的静态字段。
- 使用了由 T 声明的静态字段,并且对该字段的引用不是编译时常量(第 15.28 节)。对编译时常量的引用必须在编译时解析为编译时常量值的副本,因此使用此类字段永远不会导致初始化。
根据这一段,类的初始化会在调用静态方法之前进行,但是不清楚类的初始化是否需要在调用静态方法之前完成 .根据我的直觉,JVM应该在进入其静态方法之前要求完成类初始化,我的一些实验支持我的猜测。但是,我确实在另一个环境中看到了相反的行为。有人可以帮我解释一下吗?
感谢您的帮助。
【问题讨论】:
标签: java multithreading concurrency synchronization