nyb*_*bon 7 java concurrency multithreading synchronization
在我的应用程序中,有一个类如下:
public class Client {
public synchronized static print() {
System.out.println("hello");
}
static {
doSomething(); // which will take some time to complete
}
}
Run Code Online (Sandbox Code Playgroud)
此类将在多线程环境中使用,许多线程可以同时调用Client.print()方法.我想知道线程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应该在进入静态方法之前完成类初始化,并且我的一些实验支持我的猜测.但是,我确实在另一个环境中看到了相反的行为.有人能否对我有所了解?
任何帮助表示赞赏,谢谢.
我对引用文本的理解是,类初始化过程在调用 T 声明的静态方法之前完成(将被初始化)。
将被初始化意味着初始化过程已开始并已终止。
print因此,根据我的理解,当由于线程 A 调用而执行静态初始化程序时,另一个线程已经可以调用 ,这是不可能的print。
JLS 的第 12.4.2 章描述了详细的初始化过程,该过程负责在多线程环境中初始化类。
| 归档时间: |
|
| 查看次数: |
1961 次 |
| 最近记录: |