JAVA语言中高级特性肯定离不开多线程技术,而CountDownLatch是一个比较常用的并发工具类,它的作用:同步计数器,当计数器的值减到0时,受到影响的线程将被激活。
本文从将从业务实践中,来讲解CountDownLatch的用法,业务场景是这样的:通过后台系统倒入2W+的Excel表格,然后解析检验落库,在没优化前上传一个2000+的Excel都得100多秒,后来经过分析决定使用线程池+CountDownLatch来优化下这段程序提升了性能。
直接贴代码:
//多线程查询
long startTime2 = System.currentTimeMillis();
CountDownLatch cdl = new CountDownLatch(dates.size());
for(Map<Integer, String> data:dates){
Future<?> submit = executor.submit(new Runnable() {
@Override
public void run() {
try {
Detail Detail = buildTransDetail(data);
Detail detail = detailService.queryByChannelAndTransOrderId2(Detail.getChannel(), Detail.getId());
if (null == detail){
DetailContext.getUnSave().add(Detail);
} else {
Detail.setUpdateTime(new Date());
DetailContext.getUnUpdate().add(Detail);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
cdl.countDown();
}
}
});
}
try {
//保证线程池中的所有的线程任务都完成后,主线程才会继续向下执行;
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
这段程序主要是通过线程池去跑一个List的任务,然后使用CountDownLatch阻塞主线程,每个任务执行countDown()方法时cdl的数值都会减1,最终所有List任务都完成后,CountDownLatch的数值会减到0,await()方法阻塞结束,被阻塞主线程拿到List任务的处理结果,然后开始执行后续落库的逻辑,这只是一个简单的应用,好在是结合在业务中使用,大家有什么问题可以一起讨论。