本篇文章主要介绍CountDownLatch 相关知识。通过阅读你会有如下收获:
1. 什么是 CyclicBarrier ?
2. 如何通过CyclicBarrier 来优化对账程序 ?
3. CyclicBarrier 与CountDownLatch的区别 ?
一. CyclicBarrier 是什么?
先来看看 CyclicBarrier 的源码注释;
A synchronizati on aid that allows a set of threads to all wait for each other to reach a common barrier point.
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,所有被屏障拦截的线程才会继续干活。CyclicBarrier 默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用 await() 方法告诉 CyclicBarrier 已经到达了屏障,然后当前线程被阻塞。
二. 实战
1. 需求背景
用户通过在线商城下单,会生成电子订单,保存在订单库;之后物流会生成派送单给用户发货,派送单保存在派送单库。为了防止漏派送或者重复派送,对账系统每天还会校验是否存在异常订单。
对账系统的处理逻辑很简单,你可以参考下面的对账系统流程图。目前对账系统的处理逻辑是首先查询订单,然后查询派送单,之后对比订单和派送单,将差异写入差异库。
现有代码实现
while(存在未对账订单){
// 查询未对账订单
pos = getPOrders();
// 查询派送单
dos = getDOrders();
// 执行对账操作
diff = check(pos, dos);
// 差异写入差异库
save(diff);
}
2.分析
从上面可以看出目前整个对账流程是串行执行,优化性能首先想到的是能否利用多线程并行处理。
我们可以将查询未对账订单 getPOrders() 和查询派送单 getDOrders()并行处理,因为这两个操作并没有先后顺序的依赖。这两个最耗时的操作并行之后,执行过程如下图所示。对比一下单线程的执行,你会发现同等时间里,并行执行的吞吐量近乎单线程的 2 倍,优化效果还是相对明显的。