O thread DocumentBuilder.parse() é seguro?
-
09-06-2019 - |
Pergunta
O padrão Java é 1.6 javax.xml.parsers.DocumentBuilder classe thread segura?É seguro chamar o método parse() de vários threads em paralelo?
O JavaDoc não menciona o problema, mas o JavaDoc para a mesma classe em Java 1.4 diz especificamente que não é destinado a ser simultâneo;então posso assumir que em 1.6 é?
O motivo é que tenho vários milhões de tarefas em execução em um ExecutorService e parece caro chamar DocumentBuilderFactory.newDocumentBuilder() todas as vezes.
Solução
Mesmo que DocumentBuilder.parse pareça não alterar o construtor, ele o faz na implementação padrão do Sun JDK (baseado no Apache Xerces).Decisão de design excêntrica.O que você pode fazer?Eu acho que uso um 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);
}
}
};
(Isenção de responsabilidade:Nem tanto quanto tentei compilar o código.)
Outras dicas
Existe um método reset() no DocumentBuilder que o restaura ao estado em que foi criado pela primeira vez.Se você estiver seguindo a rota ThreadLocal, não se esqueça de ligar para isso ou você estará perdido.
Você também pode verificar este código para fazer otimizações adicionais https://svn.apache.org/repos/asf/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/xml/XmlUtil.java