2014-10-22 59 views
2

在碼頭源代碼,jetty-xml模塊,XmlConfiguration有以下代碼:爲什麼靜態最終變量使用靜態方法初始化需要同步?

java private static final XmlParser __parser = initParser(); 

private synchronized static XmlParser initParser() { 
XmlParser parser = new XmlParser(); 
URL config60 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_6_0.dtd"); 
URL config76 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_7_6.dtd"); 
URL config90 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_9_0.dtd"); 

parser.redirectEntity("configure.dtd", config90); 
parser.redirectEntity("configure_1_0.dtd", config60); 
parser.redirectEntity("configure_1_1.dtd", config60); 

... 

return parser; 

__parser可變使用initParser() initialization.the __parser應該是線程安全的靜態方法,僅由類加載器,爲什麼一度加載initParser()需要使用​​?是否過量?

進一步解釋:我調試了jetty-start模塊的Jetty源代碼,然後調用jetty-xml模塊。

+0

「XmlConfiguration.class」還有什麼其他的同步嗎? – 2014-10-22 06:50:27

+0

原子性很可能? – xTrollxDudex 2014-10-22 06:52:23

+0

也許看看介紹'synchronize'的提交可能會提供一個洞察。 – 2014-10-22 06:55:41

回答

2

我不認爲它需要完全同步。

Java語言規範保證在鎖內執行Java類初始化(即類的初始化等)以防止競爭條件。無論該類是加載一次還是多次(即通過不同的類加載器),這都適用。

我懷疑這段代碼的作者根本不知道JVM如何處理這個,並且正在採取不必要的預防措施。

(在另一方面,這些「帶和大括號」的預防措施是無害的,並且對性能的影響是微不足道的。大概不可測量)


爲了記錄在案,爲類的初始化過程中指定JLS在Section 12.4.2

+0

是的,我同意。我已經提交了一個錯誤碼頭,問爲什麼。看看他們如何回覆。 – ykgarfield 2014-10-22 08:13:33

+0

@ykgarfield - 我預測他們會關閉狀態「不會修復」或類似的狀態。如果它沒有損壞,請不要修復它! – 2014-10-22 10:28:35

+0

哈哈,我收到作者回復,'synchronized'沒有必要,他們會修正它。不管怎樣,再次感謝。:) – ykgarfield 2014-10-30 03:09:24

0

如果你確定至多有一個類加載器,那麼就不需要同步。靜態初始化代碼每個類加載器運行一次。

從我可以在Jetty WebAppContext中看到的只有一個類加載器可以在配置中設置。

+0

無論如何,謝謝,作者將解決它。'同步'沒有必要 – ykgarfield 2014-10-30 03:10:25

+0

甜,如果你喜歡你可能給我一個upvote) – Dennis 2014-10-31 10:00:00