我们已经在生产中使用Apache POI几年并取得了良好的效果。目前在3.11版本上。我们只使用HSSF(根据我们的测试,比XSSF更快,我们可以不使用XLSX。)
我们目前保留了“同步工作簿运行者”的缓存映射,大约70左右的内存。想想每个XLS产品,地图键告诉我们使用哪个产品。我们在启动时加载缓存,所以我们永远不会实时读取文件。
我们的同步跑步者大致如下:
public class PoiProcessorSynchronized {
private Workbook workbook;
public synchronized Map<String, Object> process(Request request) {
engine.process(workbook, request); //request has input/output params
}
}
这使得性能相当不错(过去24小时平均为112k,平均为112k),有些纸张很慢,有些很快。我们在处理之间手动将输入重置到工作表中,以确保工作表之间的工作表是清洁的。
保持对工作表的同步处理是为了防止错误计算。我们最初看到一些错误的计算而没有控制对纸张的访问。自从我们这样做以来,它一直很稳固。
我担心的一些问题:
还有其他人试图做类似的事吗?这种方法现在正在发挥作用,但感觉应该有更好的方法。
我们可以缓存其他工作簿吗?或序列化什么?
有没有人通过工作簿成功处理高容量而不同步它们?如果是这样的话?
答案 0 :(得分:2)
在库级别,Apache POI是线程安全的。在工作簿级别(+ sheet / row / cell / etc级别),Apache POI不是线程安全的。给定的工作簿一次只能由一个线程处理。如果您有多个并行工作的线程,则它们必须具有自己的工作簿才能进行处理。不支持在同一工作簿上工作的两个线程(包括在同一工作簿中处理不同的工作表)。
总的来说,加载.xls文件相当快。使用File rather than an InputStream if you can稍微降低内存并加快加载速度。请参阅memory and performance FAQ for some guides。确保您使用最新版本的Apache POI进行bug fixes and improvements
对于您的特定情况,最流行的工作簿的某种缓存可能会很好。也许只适用于较大的流行工作簿,小型工作簿总是按需加载。
否则,尝试进行一些分析,看看POI是否在某些地方为某些文件做了太多工作。然后report that and work to get it fixed,项目总是欢迎性能提升!
答案 1 :(得分:1)
这个问题的答案完全取决于POI本身是否以完全线程安全的方式实现。
鉴于并发和线程安全未在POI站点上的文档或FAQ中的任何地方解决,您必须假设它不是线程安全的。
快速查看POI 3.5 HSSFWorkbook code at DocJar显示没有同步关键字,并且使用了简单的非同步集合......所以不,它不是线程安全的。
因此,您的同步方法可能是您所能做到的最佳方法。