2012-02-02 3 views
7

javax.xml.XPathFactory.newInstance()는 스레드로부터 안전한가요?Java XPathFactory 스레드 안전성

설명서가 모호하기 때문에 묻습니다. The JDK 5 docs에는 thread-safety가 전혀 언급되어 있지 않습니다. JDK 6에서 그들은 다음과 같이 썼습니다 :

XPathFactory 클래스는 스레드로부터 안전하지 않습니다. 즉, 주어진 순간에 하나의 스레드가 인 XPathFactory 객체를 사용하도록하는 것은 응용 프로그램의 책임이므로 응용 프로그램의 책임입니다. 구현은 깨진 클라이언트에서 자신을 보호하기 위해 동기화 된 것으로 메소드를 표시하도록 권장합니다.

내가 알고있는 것처럼,이 XPathFactory에 대한 싱글 구현을 가지고 안전 아니지만, 이런 일을 뭔가가 안전해야 :

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

내가 뭔가를 놓치고 있습니까? 그것을 확장하는 실제 클래스에 의존합니까? 위의 문장이 포함 된 메서드 synchronize해야합니까?

답변

11

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

모든 스레드가 자체 공장을 갖기 때문에 안전합니다 (newInstance() 덕분에). 동기화 할 필요가 없습니다.

안전하게 수행 할 수없는 작업은 공장을 단 한 번 가져온 다음 동기화없이 스레드간에 공유하는 것입니다 (예 : 싱글 톤). XPath 인스턴스 (xPathEvaluator) 자체에 대해서도 마찬가지입니다.

+0

감사합니다. 나는 같은 생각을하고 있었지만 재 보증을 원했습니다. :). –

+1

항상 손을 잡고 여기 있습니다 :-) – Thilo

+5

JAXP-XPath 디자인에 관한 여러 가지 나쁜 점이 있습니다. 그 중 하나는 XPathFactory.newInstance()가 매우 비싸다는 것입니다. 또 다른 점은 모든 스레드에서 반복적으로 호출 할 것으로 예상된다는 것입니다. 또 다른 방법은 XPath 1.0 엔진이나 XPath 2.0 엔진을 다시 사용할 것인지 여부를 알 수있는 방법이 없다는 것입니다. 이 메커니즘을 실제로 사용할지 여부를 자문 해보십시오. 원하는 XPath 엔진을 알고 있으면 더 나은로드 방법이 있습니다. –

3

"그 중 하나는 XPathFactory.newInstance()가 매우 비쌉니다."

True 진술! 나는 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하는) 기본 호출을하고 디스크를 필요로하는 항아리, 압축 해제 입출력 및 프로세서 바인드 압축 해제. 이 경우 우리는 1400 개 이상의 스레드가 해당 잠금을 기다리고있었습니다.