我很难决定以下两个实现方案。我想为每个线程缓存javax.xml.parsers.DocumentBuilder对象。我的主要关注点是运行时性能 - 因此,我希望尽可能避免GC。内存不是问题。
我编写了两个POC实现,并乐于听取社区对每个实现的优缺点的意见。
谢谢大家的帮助。
选项#1 - WeakHashMap
import java.io.IOException;
import java.io.StringReader;
import java.util.WeakHashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class DocumentBuilder_WeakHashMap {
private static final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
private static final WeakHashMap<Thread, DocumentBuilder> CACHE = new WeakHashMap<Thread, DocumentBuilder>();
public static Document documentFromXMLString(String xml) throws SAXException, IOException, ParserConfigurationException {
DocumentBuilder builder = CACHE.get(Thread.currentThread());
if(builder == null) {
builder = factory.newDocumentBuilder();
CACHE.put(Thread.currentThread(), builder);
}
return builder.parse(new InputSource(new StringReader(xml)));
}
}
Option #2 - ThreadLocal
import java.io.IOException;
import java.io.StringReader;
import java.lang.ref.WeakReference;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class DocumentBuilder_ThreadLocal {
private static final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
private static final ThreadLocal<WeakReference<DocumentBuilder>> CACHE =
new ThreadLocal<WeakReference<DocumentBuilder>>() {
@Override
protected WeakReference<DocumentBuilder> initialValue() {
try {
return new WeakReference<DocumentBuilder>(factory.newDocumentBuilder());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
public static Document documentFromXMLString(String xml) throws ParserConfigurationException, SAXException, IOException {
WeakReference<DocumentBuilder> builderWeakReference = CACHE.get();
DocumentBuilder builder = builderWeakReference.get();
if(builder == null) {
builder = factory.newDocumentBuilder();
CACHE.set(new WeakReference<DocumentBuilder>(builder));
}
return builder.parse(new InputSource(new StringReader(xml)));
}
}
它们都可以实现相同的功能(将documentFromXMLString()暴露给外部),所以你会选择哪一个?
谢谢, Maxim。