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)最好,但是这样做安全吗?还可以避免被同步阻止吗?我希望它尽快。
谢谢?
如果要重用线程(如在线程池中),则可以声明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在解析时是线程安全的,则可以使用与我所述相同的机制。
此分辨率将使总吞吐量尽可能快。
注意:这未经测试或编译只是给出了我所指的概念。