28

Is the standard Java 1.6 javax.xml.parsers.DocumentBuilder class thread safe? Is it safe to call the parse() method from several threads in parallel?

The JavaDoc doesn't mention the issue, but the JavaDoc for the same class in Java 1.4 specifically says that it isn't meant to be concurrent; so can I assume that in 1.6 it is?

The reason is that I have several million tasks running in an ExecutorService, and it seems expensive to call DocumentBuilderFactory.newDocumentBuilder() every time.

CodeMonkey
  • 22,825
  • 4
  • 35
  • 75
Avi
  • 19,934
  • 4
  • 57
  • 70

3 Answers3

28

Even though DocumentBuilder.parse appears not to mutate the builder it does on the Sun JDK default implementation (based on Apache Xerces). Eccentric design decision. What can you do? I guess use a ThreadLocal:

private static final ThreadLocal<DocumentBuilder> builderLocal =
    new ThreadLocal<DocumentBuilder>() {
        @Override protected DocumentBuilder initialValue() {
            try {
                return
                    DocumentBuilderFactory
                        .newInstance(
                            "xx.MyDocumentBuilderFactory",
                            getClass().getClassLoader()
                        ).newDocumentBuilder();
            } catch (ParserConfigurationException exc) {
                throw new IllegalArgumentException(exc);
            }
        }
    };

(Disclaimer: Not so much as attempted to compile the code.)

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
22

There's a reset() method on DocumentBuilder which restores it to the state when it was first created. If you're going the ThreadLocal route, don't forget to call this or you're hosed.

Jherico
  • 28,584
  • 8
  • 61
  • 87
Trenton
  • 11,678
  • 10
  • 56
  • 60
4

You can also check this code to make further optimization https://svn.apache.org/repos/asf/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java

Koray Güclü
  • 2,857
  • 1
  • 34
  • 30