使用countdownlatch拆分任务踩坑记录

本文介绍了一种利用CountDownLatch和固定线程池进行并行数据查询的策略,以提高按月查询时的数据处理效率。通过将查询任务分割为多个子任务并发执行,最后汇总结果,实现了对大量数据的有效管理和快速响应。

1.因有个需求, 此需求是需要单查数据才可以查询准确的数据,但是前台参数是 按月份查询,所以需要查询月区间的每天的数据
2.使用countdownlatch
3.使用 private static ExecutorService executorService = Executors.newFixedThreadPool(5);
4.举例 8.1 - 9.30号,查看区间有多少天, 分割成5份,最后一份加上余数
6.每个线程中查询的对象,不可通用
7.举例

	//例子
    BigDecimal sta = new BigDecimal(start.getTime());
    executorService.execute(new Runnable() {
        @Override
        public void run() {
                for(int i = 0 ;i < every;i++){

                    BigDecimal sta2 = new BigDecimal(0);
                    sta2 = sta.add(new BigDecimal(i * 24 *60 *60 *1000));
                    start.setTime(sta2.longValue());


                    bomberDistributionFroms.setDayTime(DateUtilsSync.formatYMD(start));
                    List<Map<String, Object>> bomberDistributionReportForm = applicationMapper.getBomberCollectionReceiptStock(bomberDistributionFroms);
                    bomberDistributionReportFormResult.addAll(bomberDistributionReportForm);
                }
                countDownLatch.countDown();
        }
    });

	//对照
    BomberDistributionFroms finalBomberDistributionFroms = bomberDistributionFroms2;
    BigDecimal sta8 = new BigDecimal(start2.getTime());
    executorService.execute(new Runnable() {
        @Override
        public void run() {
                    BigDecimal sta2 = new BigDecimal(0);
                    sta2 = sta8.add(new BigDecimal(i * 24 *60 *60 *1000));
                    start2.setTime(sta2.longValue());

                    finalBomberDistributionFroms.setDayTime(DateUtilsSync.formatYMD(start2));
                    List<Map<String, Object>> bomberDistributionReportForm = applicationMapper.getBomberCollectionReceiptStock(finalBomberDistributionFroms);
                    bomberDistributionReportFormResult.addAll(bomberDistributionReportForm);
                }
                countDownLatch.countDown();
        }
    });
    //最后 主线程等待
    try {
        countDownLatch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

添加数据的list需要用 sync的list

### Java 中使用 `CountDownLatch` 和线程池执行多个并发任务 为了实现多个任务的并发执行以及同步操作,在Java中可以结合使用`CountDownLatch`和线程池。下面是一个具体的例子,展示了如何创建一定数量的工作线程去处理各自独立的任务,并通过`CountDownLatch`确保所有工作完成后才继续后续流程。 #### 创建定时线程池对象并设置线程池线程数量固定为5 ```java // 初始化一个大小固定的调度型线程池 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); ``` 定义待运行的任务逻辑,这里假设每个任务模拟一段耗时操作: ```java final int numberOfTasks = 5; CountDownLatch countDownLatch = new CountDownLatch(numberOfTasks); for (int i = 0; i < numberOfTasks; ++i) { final int taskId = i + 1; // 提交带有计数器减法动作的任务给线程池 scheduledThreadPool.submit(() -> { try { System.out.printf("Task %d is starting...\n", taskId); Thread.sleep((long)(Math.random() * 3000)); // 模拟不同长度的任务延迟 System.out.printf("Task %d has completed.\n", taskId); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage()); } finally { countDownLatch.countDown(); // 当前任务结束,减少倒计数值 } }); } ``` 等待所有的子任务完成后再做其他事情: ```java try { countDownLatch.await(); // 主线程在此处阻塞直到countdownLatch达到零 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("All tasks have been executed."); scheduledThreadPool.shutdown(); // 关闭线程池 ``` 上述代码片段实现了如下功能:启动了一个包含五个线程的线程池;向该线程池提交了若干个异步任务实例;这些任务会在各自的线程上被执行完毕后调用`countDown()`方法通知主线程它们已经完成了自己的工作;最后当所有任务都报告已完成时,主线程才会解除挂起状态继续向前推进[^1]。 #### 结合实际应用场景说明 在一个电商网站的商品详情页面加载过程中,可能涉及到从不同的微服务接口获取商品信息、库存情况、用户评价等多个方面的数据。如果不采用并发的方式依次请求,则会显著增加整个页面渲染所需的时间。因此可以通过构建类似的机制让各个查询尽可能同时发起,从而提高响应速度和用户体验[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值