CountDownLatch 的作用
- 假设有主线程A、子线程B、子线程C
- A里有一个List,和一个map
- List由子线程B和C共同处理,B处理一部分,C处理一部分
- 当子线程B和C都将结果处理完后,再分别将处理结果放入A线程的map中
- 当子线程B和C都处理完后,主线程A再进行操作
- 总结:说白了就是,A线程需要等待B和C线程的处理结果
CountDownLatch 例子:
/**
* 实现功能是将goodsReqDtoList作为calcEstimateAmount方法的入参,然后将最终的结果放入resMap中进行返回
* 1.根据 goodsReqDtoList 的长度,判断我们要开多少个线程
* 2.将每个线程获得的结果放入 map 中,等到所有线程都计算完,将结果进行返回
* @param goodsReqDtoList CommonGoodsReqDto,支持多个商品属性的查询
* @return
*/
@Override
public Map<String, Long> getRebatePlanAmount(List<CommonGoodsReqDto> goodsReqDtoList) {
// 1.线程执行数量,判断要开多少个线程执行
int threadNum;
int everyListCount = 5; // 每个list中有5条数据
if (goodsReqDtoList.size() % everyListCount == 0) {
threadNum = goodsReqDtoList.size() / everyListCount;
} else {
threadNum = goodsReqDtoList.size() / everyListCount + 1;
}
// 2. 对每个线程的结果进行计算,并将它们的结果放到 resMap 中作为 getRebatePlanAmount 方法的返回参数
final Map<String, Long> resMap = new ConcurrentHashMap<>();
final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
List<CommonGoodsReqDto> goodsList = new ArrayList<>();
for (int i = 0; i < goodsReqDtoList.size(); i++) {
goodsList.add(goodsReqDtoList.get(i));
if ((i == goodsReqDtoList.size() - 1) || (i + 1) % everyListCount == 0) {
final List list = goodsList;
new Thread(new Runnable() {
@Override
public void run() {
// 将每个线程获得的结果放到 resMap 中
resMap.putAll(calcEstimateAmount(list));
countDownLatch.countDown();
}
}).start();
}
if ((i + 1) % everyListCount == 0) {
goodsList = new ArrayList<>();
}
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return resMap;
}