相同点:
日常使用当中我们一般用CountDownLatch做减法操作,用CyclicBarrier做加法操作,殊不知其实这两个具有异曲同工之妙,CountDownLatch通过它的countDown()使得任务减一,通过await()来判断其是否任务结束,如果没有结束则阻塞,结束则执行下一步操作。而CyclicBarrier则是通过await()来阻塞,当其它的异步任务都执行结束后,则执行下一步操作。简单来说如果没有顺序要求,那就正如1到7和7到1一样,使用没有什么明显区别,最终的执行结果都是一样的,如下所示CyclicBarrier的简单使用
/**
* 三类物质管理(贴钱危化品、危化回收物料、危险废物)
* @return
*/
@Override
public List<ThreeMaterialManage> getMaterialManage(Long deptId) {
//用来封装和返回展示数据的数据集合
ArrayList<ThreeMaterialManage> threeMaterialManages = new ArrayList<>();
//用来封装贴钱危化品的查询结果
ThreeMaterialManage saleMaterial = new ThreeMaterialManage(deptId);
//用来封装危化回收物料的查询结果
ThreeMaterialManage middleMaterial = new ThreeMaterialManage(deptId);
//用来封装危险废物的查询结果
ThreeMaterialManage dangerMaterial = new ThreeMaterialManage(deptId);
//用来封装危险废物的查询结果
CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
threeMaterialManages.add(saleMaterial);
threeMaterialManages.add(middleMaterial);
threeMaterialManages.add(dangerMaterial);
});
//创建线程池来处理三类物质不同的数据统计结果
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,
3,
5L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3));
try{
//处理贴钱危化品的异步执行任务
CompletableFuture.runAsync(()->{
//物料类别 1:贴钱危化品 2:中间物料 3:危险废物
Integer matType = 1;
saleMaterial.setMatType(matType);
queryMaterialManage(saleMaterial);
try{
cyclicBarrier.await();
}catch(Exception e){
e.printStackTrace();
}
},threadPoolExecutor);
//处理危化回收物料的异步执行任务
CompletableFuture.runAsync(()->{
//物料类别 1:贴钱危化品 2:中间物料 3:危险废物
Integer matType = 2;
middleMaterial.setMatType(matType);
queryMaterialManage(middleMaterial);
try{
cyclicBarrier.await();
}catch(Exception e){
e.printStackTrace();
}
},threadPoolExecutor);
//处理危险废物的异步执行任务
CompletableFuture.runAsync(()->{
//物料类别 1:贴钱危化品 2:中间物料 3:危险废物
Integer matType = 3;
dangerMaterial.setMatType(matType);
queryMaterialManage(dangerMaterial);
try{
cyclicBarrier.await();
}catch(Exception e){
e.printStackTrace();
}
},threadPoolExecutor);
}catch(Exception e){
e.printStackTrace();
}finally {
threadPoolExecutor.shutdown();
}
return threeMaterialManages;
}
CyclicBarrier构造参数的第一个为阻塞等待线程数量,第二个为消费型函数式接口,来指定当线程全部放开后的执行逻辑
不同点:CountDownLatch的awite()方法阻塞的是当前最后一个判断是否减法到0的主线程,而CyclicBarrier阻塞的是在线程数未达到指定数量的所有线程