在我的應用程序,還有一類象下面這樣:類初始化和同步類方法
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