DOM API上的Java多线程

Cra*_*lus 3 java multithreading dom jaxp thread-safety

我有一个执行xml解析的功能。我想使函数线程安全,但也要尽可能优化(减少阻塞)。
简而言之,代码如下:

public Document doXML(InputStream s)
{
//Some processing.
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  DocumentBuilder parser = factory.newDocumentBuilder();
  Document xmlDoc = parser.parse(is);
  return xmlDoc;

}
Run Code Online (Sandbox Code Playgroud)

但是我不想在每个调用中创建一个新的DocumentBuilderFactory或DocumentBuilder。
我想重用工厂和解析器,但是我不确定它们是线程安全的。那么最佳方法是什么?
1)将DocumentBuilderFactory缓存在类字段中,并同步factory.newDocumentBuilder(); 这样每个线程都有自己的DocumentBuilder实例
。2)缓存一个DocumentBuilderFactory DocumentBuilder并同步parser.parse(is);
我认为每个线程(2)最好,但是这样做安全吗?还可以避免被同步阻止吗?我希望它尽快。

谢谢?

Joh*_*int 5

如果要重用线程(如在线程池中),则可以声明DocumentBuilderFactory为线程本地。为每个线程创建一个新的集合会有开销,但是正如我所说,如果要重新调用,则后续开销非常低。

final ThreadLocal<DocumentBuilderFactory> documentBuilderFactor = new ThreadLocal<DocumentBuilderFactory>(){
     public DocumentBuilderFactory  initialValue(){
       return  DocumentBuilderFactory.newInstance();
     }
}

public Document doXML(InputStream s)
{
//Some processing.
  DocumentBuilderFactory factory = documentBuilderFactor.get();
  DocumentBuilder parser = factory.newDocumentBuilder();
  Document xmlDoc = parser.parse(is);
  return xmlDoc;

}
Run Code Online (Sandbox Code Playgroud)

在这里,您将仅为每个线程创建一个DocumentBuilderFactory。

我不知道DocumentBuilder在解析时是否是线程安全的(它是不可变的吗?)。但是,如果DocumentBuilder在解析时是线程安全的,则可以使用与我所述相同的机制。

此分辨率将使总吞吐量尽可能快。

注意:这未经测试或编译只是给出了我所指的概念。