Java XPathFactory потокобезопасность - PullRequest
8 голосов
/ 02 февраля 2012

Является ли javax.xml.XPathFactory.newInstance () поточно-ориентированным?

Я спрашиваю, потому что нахожу документацию неоднозначной для этого. Документы JDK 5 вообще не упоминают о безопасности потоков; в JDK 6 они написали следующее:

Класс XPathFactory не является поточно-ориентированным. Другими словами, это ответственность приложения за обеспечение того, чтобы не более одного потока использование объекта XPathFactory в любой момент. Реализации рекомендуется помечать методы как синхронизированные, чтобы защитить себя от сломанные клиенты.

Насколько я понимаю, иметь одноэлементную реализацию для XPathFactory небезопасно, но делать что-то подобное должно быть безопасно:

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

Я что-то упустил? Это зависит от фактического класса, который расширяет это? Нужно ли synchronize метод, который содержит приведенное выше утверждение?

Ответы [ 2 ]

14 голосов
/ 02 февраля 2012

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

Это безопасно, поскольку каждый поток получает свою собственную фабрику (благодаря newInstance()).Здесь не нужно синхронизировать.

То, что вы не можете безопасно сделать, это получить фабрику только один раз, а затем разделить ее между потоками без синхронизации, например, в виде одиночного файла.То же самое касается самого экземпляра XPath (xPathEvaluator).

5 голосов
/ 08 марта 2013

"Одним из них является то, что 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-файл, который требует дискового ввода-вывода и распаковки zip с привязкой к процессору. В этом случае у нас было более 1400 потоков, ожидающих этой блокировки.

...