在我的应用程序,还有一类象下面这样:类初始化和同步类方法
public class Client {
public synchronized static print() {
System.out.println("hello");
}
static {
doSomething(); // which will take some time to complete
}
}
这个类将在多线程环境中使用的,许多线程可同时调用Client.print()方法。我想知道是否有线程1触发类初始化的机会,并且在类初始化完成之前,线程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应该要求完成类初始化,并且我的一些实验支持我的猜测。但是,我在另一个环境中看到了相反的行为。有人可以帮我解释一下吗?
任何帮助表示赞赏,谢谢。
静态初始化器是一个简单的类方法,它是在锁(类加载器的一个)下调用的。 –
bestsss
2011-01-10 20:14:15