2012-02-02 54 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个线程在等待这个锁。