这几天因为创建Excel的性能问题,头疼了几天。
先说下我的需求:根据场次导出Excel,有多少个场次就有多少个sheet页。根据工具调试,发现创建WorkBook和Sheet真的很耗时,差不多要大约两秒的时间,所以想用多线程去操作。但是创建sheet的方法底层并没有做加锁处理,导致它每次创建都会去读当前的sheet总数,所以无法放到多线程中。由于这边的场次量很多,数据量也很大,和产品商量讨论之后,决定使用每个场次创建一个Excel,然后打包成zip。
为了避免开启线程太多,所以使用了线程池和计数器(countdownLatch),生成完所有的Excel在进行压缩
下面是代码:
/**
* 具体的线程操作方法
* @param response
* @throws IOException
*/
public void test(HttpServletResponse response) throws IOException {
int num = 20;
//ThreadPoolExecutor的用法 请参见这位老哥的帖子 https://www.iteye.com/blog/coach-855850
ThreadPoolExecutor executor = new ThreadPoolExecutor(20, 500, 10L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(100));
CountDownLatch count = new CountDownLatch(num); //这里的num是我的场