在我的项目中,我尝试使用 java 中的同步在多个线程中使用
,因为根据文档 XsltTransformer 不得在多个线程中同时使用。然而,在单个线程中重用该对象来多次运行相同的样式表是安全的。运行样式表不会更改已建立的上下文。一些公共方法是同步的:这并不是因为支持多线程执行,而是为了减少尝试多线程执行时的损害。但在尝试使用 JMeter 每秒发送 100 个请求进行压力测试时,我发现net.sf.saxon.s9api.XsltTransformer
需要更多时间,有时会达到 6 分钟。 如何在多线程中使用net.sf.saxon.s9api.XsltTransformer.transform()
而不影响性能?net.sf.saxon.s9api.XsltTransformer.transform()
我尝试将 TransformerSingleton 类制作如下
public class TransformerSingleton {
private static XsltTransformer transformer;
private TransformerSingleton() {
}
public static void xsltLoad() {
if (transformer == null) {
synchronized (XsltTransformer.class){
try {
Processor processor = new Processor(false);
XsltCompiler compiler = processor.newXsltCompiler();
XsltExecutable xslt = compiler.compile(new StreamSource("/my_path/"));
transformer = xslt.load();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static XsltTransformer getTransformer(){
if (transformer == null) {
synchronized (XsltTransformer.class) {
xsltLoad();
}
} return transformer;
}
}
public static void main(String[] args) {
XsltTransformer transformer = XsltTransformerSingleton.getTransformer();
String xml = "<Users><name>AAA</name></Users>"; // for example
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(xml.getBytes())) {
synchronized (transformer){
ksaTransformer.setSource(new StreamSource(byteArrayInputStream));
XdmDestination chainResult = new XdmDestination();
ksaTransformer.setDestination(chainResult);
ksaTransformer.transform();
}
}
}
预计吞吐量将达到每秒 100 个请求。 实际上我达到了每秒 60 次。
在多个线程中并行运行相同样式表的方法是将样式表一次编译为
XsltExecutable
,然后为每个转换创建一个新的XsltTransformer
。从 XsltTransformer
创建 XsltExecutable
非常便宜。