2012-02-02 104 views
7

是javax.xml.XPathFactory.newInstance()線程安全嗎?Java XPathFactory線程安全

我在問,因爲我發現文檔含糊不清。 The JDK 5 docs根本不提線程安全;在JDK 6他們寫了以下內容:

XPathFactory類不是線程安全的。換句話說, 應用程序的責任是確保在任何給定時刻至多有一個線程是 使用XPathFactory對象。鼓勵實施方案 將方法標記爲同步,以保護自己免受破損的客戶端的攻擊。

據我所知,這不是安全有單實施XPathFactory,但做這樣的事情應該是安全的:

XPath xPathEvaluator = XPathFactory.newInstance().newXPath(); 

我缺少的東西?它取決於擴展它的實際類嗎?我是否需要synchronize包含上述語句的方法?

回答

11

XPath xPathEvaluator = XPathFactory.newInstance()。newXPath();

這是安全的,因爲每個線程都有自己的工廠(感謝newInstance())。無需在此同步。

你不能安全地做的就是讓工廠一次,然後在沒有同步的線程之間共享它,例如作爲一個單例。 XPath實例(xPathEvaluator)本身也是如此。

+0

謝謝,我在想同樣的事情,但我想重新保證:)。 – 2012-02-02 10:27:00

+1

總是在這裏牽手:-) – Thilo 2012-02-02 12:50:57

+5

JAXP-XPath設計有很多不好的地方。其中之一是XPathFactory.newInstance()非常昂貴;另一個是你需要在每個線程中重複地調用它。另一個原因是你無法知道你是否會獲得XPath 1.0引擎或XPath 2.0引擎。問問你自己是否真的想使用這種機制:如果你知道你想要的XPath引擎,有更好的方法來加載它。 – 2012-02-02 14:01:10

3

「其中之一是XPathFactory.newInstance()非常昂貴;」

真實的陳述!我注意到,爲每個線程調用的newInstance(),jaxp.properties必須位於類路徑和閱讀:

java.lang.Thread.State: BLOCKED (on object monitor) 
     at java.util.zip.ZipFile.getEntry(ZipFile.java:160) 
     - locked <0x0000000968dec028> (a sun.net.www.protocol.jar.URLJarFile) 
     at java.util.jar.JarFile.getEntry(JarFile.java:208) 
     at sun.net.www.protocol.jar.URLJarFile.getEntry(URLJarFile.java:107) 
     at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:114) 
     at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:132) 
     at java.net.URL.openStream(URL.java:1010) 
     at javax.xml.xpath.SecuritySupport$4.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at javax.xml.xpath.SecuritySupport.getURLInputStream(Unknown Source) 
     at javax.xml.xpath.XPathFactoryFinder._newFactory(Unknown Source) 
     at javax.xml.xpath.XPathFactoryFinder.newFactory(Unknown Source) 
     at javax.xml.xpath.XPathFactory.newInstance(Unknown Source) 
     at javax.xml.xpath.XPathFactory.newInstance(Unknown Source) 

的ZipFile使得本地電話(爲zlib我相信)和解壓的jar,這需要磁盤IO和處理器綁定的zip解壓縮。在這個例子中,我們有超過1400個線程在等待這個鎖。