java DocumentBuilder.parse() 线程安全吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/56737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:52:51  来源:igfitidea点击:

Is DocumentBuilder.parse() thread safe?

javathread-safety

提问by Avi

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

标准的 Java 1.6 javax.xml.parsers.DocumentBuilder类线程安全吗?从多个线程并行调用 parse() 方法是否安全?

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

JavaDoc 没有提到这个问题,但Java 1.4 中同一个类JavaDoc明确指出它不是并发的;所以我可以假设在 1.6 中是这样吗?

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

原因是我有几百万个任务在 ExecutorService 中运行,每次调用 DocumentBuilderFactory.newDocumentBuilder() 似乎很昂贵。

采纳答案by Tom Hawtin - tackline

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:

尽管 DocumentBuilder.parse 似乎不会改变它在 Sun JDK 默认实现(基于 Apache Xerces)上所做的构建器。古怪的设计决策。你能做什么?我想使用 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.)

(免责声明:不是试图编译代码。)

回答by Trenton

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.

DocumentBuilder 上有一个 reset() 方法,可以将其恢复到首次创建时的状态。如果您要使用 ThreadLocal 路线,请不要忘记调用它,否则您将被冲洗掉。