gpt4 book ai didi

java - DocumentBuilder 线程安全吗?

转载 作者:IT老高 更新时间:2023-10-28 20:55:40 25 4
gpt4 key购买 nike

我正在查看的当前代码库使用 DOM 解析器。以下代码片段在 5 种方法中重复:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

如果在循环中调用包含上述代码的方法或在应用程序中多次调用该方法,我们将承担为每次调用此类方法创建一个新 DocumentBuilderFactory 实例和一个新 DocumentBuilder 实例的开销.

如下所示,围绕 DocumentBuilder 工厂和 DocumentBuilder 实例创建一个单例包装器是不是一个好主意:

public final class DOMParser {
private DocumentBuilderFactory = new DocumentBuilderFactory();
private DocumentBuilder builder;

private static DOMParser instance = new DOMParser();

private DOMParser() {
builder = factory.newDocumentBuilder();
}

public Document parse(InputSource xml) {
return builder.parser(xml);
}
}

如果上面的单例在多个线程之间共享,会出现什么问题吗?如果不是,那么在应用程序的整个生命周期中只使用一次创建 DocumentBuilderFactory 和 DocumentBuilder 实例的上述方法是否会提高性能?

编辑:

我们唯一可能遇到的问题是 DocumentBuilder 在解析 XML 文件时是否保存了一些状态信息,这可能会影响下一个 XML 文件的解析。

最佳答案

有关同一问题的其他问题,请参见评论部分。 简短回答您的问题:不,将这些类放在一个单例中是不正确的。 DocumentBuilderFactory 和 DocumentBuilder 都不能保证是线程安全的。如果您有多个解析 XML 的线程,请确保每个线程都有自己的 DoumentBuilder 版本。每个线程只需要其中一个,因为您可以在重置后重用 DocumentBuilder。

编辑一小段代码表明使用相同的 DocumentBuilder 是不好的。对于 java 1.6_u32 和 1.7_u05,此代码失败并出现 org.xml.sax.SAXException: FWK005 parse may not be called while parsing。在构建器上取消注释同步,它工作正常:

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();

ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
exec.submit(new Runnable() {
public void run() {
try {
// synchronized (builder) {
InputSource is = new InputSource(new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\" ?><俄语>данные</俄语>"));
builder.parse(is);
builder.reset();
// }
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
exec.shutdown();

这就是你的答案 - 不要从多个线程调用 DocumentBuilder.parse()。是的,这种行为可能是特定于 JRE 的,如果您使用的是 IBM java 或 JRockit 或给它一个不同的 DocumentBuilderImpl,它可能工作正常,但对于默认的 xerces 实现 - 它不会。

关于java - DocumentBuilder 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12455602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com