Java XPathFactory线程安全

Ale*_*ian 9 java xml xpath thread-safety

javax.xml.XPathFactory.newInstance()线程安全吗?

我问,因为我发现文档含糊不清.JDK 5文档根本没有提到线程安全性; 在JDK 6中,他们写了以下内容:

XPathFactory类不是线程安全的.换句话说,应用程序有责任确保在任何给定时刻最多只有一个线程正在使用XPathFactory对象.鼓励实现将方法标记为同步以保护自己免受破坏的客户端的影响.

据我所知,单独实现XPathFactory是不安全的,但做这样的事情应该是安全的:

XPath xPathEvaluator = XPathFactory.newInstance().newXPath();
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?它取决于扩展它的实际类吗?我需要synchronize包含上述语句的方法吗?

Thi*_*ilo 14

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

这是安全的,因为每个线程都有自己的工厂(感谢newInstance()).无需在此处同步.

你不能安全做的是只让工厂一次,然后在没有同步的情况下在线程之间共享它,例如作为单例.XPath实例(xPathEvaluator)本身也是如此.

  • JAXP-XPath设计有很多不好的地方.其中之一是XPathFactory.newInstance()非常昂贵; 另一个是你应该在每个线程中反复调用它.另一个原因是您无法知道是否会返回XPath 1.0引擎或XPath 2.0引擎.问问自己是否真的想要使用这种机制:如果你知道你想要什么XPath引擎,有更好的方法来加载它. (6认同)
  • 嗨迈克尔,有什么更好的方法加载XPath引擎? (4认同)
  • 根据Javadoc http://docs.oracle.com/javase/6/docs/api/javax/xml/xpath/XPathFactory.html:`XPathFactory不可重入.当正在调用其中一个newInstance方法时,应用程序可能不会尝试递归调用newInstance方法,即使是来自同一个线程.,XPathFactory.newInstance()也不安全.需要同步.但是,我读了XPathFactory的源代码,无法弄清楚哪个操作不安全. (4认同)
  • 这个答案不同意文档.该文档明确指出:"在调用其中一个`newInstance`方法时,应用程序可能不会尝试以递归方式调用newInstance方法,即使是在同一个线程中也是如此." 这不是关于实例_returned by_` newInstance`是否是线程安全的,它是关于对`XPathFactory.newInstance()`的调用,它是一个_static方法_是否是线程安全的.两个线程很容易调用相同的静态方法@Thilo. (2认同)

小智 5

"其中一个是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)
Run Code Online (Sandbox Code Playgroud)

ZipFile进行本机调用(我相信zlib)并解压缩jar,这需要磁盘IO和处理器绑定的zip解压缩.在这个例子中,我们有1400多个线程在等待锁定.