多线程中,对大集合的批处理案例

场景:在一个方法中,需要解析一个List对象集合,list长度1000+,单线程同步处理执行缓慢,故而使用多线程方式分批处理。

步骤如下:

1.待处理集合

//待处理集合:
List<Object> list = new ArrayList<Object>;

//调用partition方法,将list分割为10个为一组
List<List<PartitionModel>> partitionList = Lists.partition(list , 10);
int syncSize = partitionList.size();

//使用 CountDownLatch 设置计数器
CountDownLatch threadLatch = new CountDownLatch(syncSize);

//这两个容器作用是存储子线程执行结果
BlockingDeque<Boolean> resultList = new LinkedBlockingDeque<>(syncSize);
List<Future<Boolean>> futures = Lists.newArrayList();

//创建回滚控制容器
RollBack rollBack = new RollBack(false);

//创建子线程返回提示语容器
List<ResultMsg> resultMsgs = new LinkedList<>();

// 设置循环结束关键字
while (syncSize > 0) {
      List<PartitionModel> models = partitionList.get(syncSize - 1);
      LOGGER.info("开始第{}批次循环,本次执行的列表:{}", syncSize,
                                 invoiceModels));

       Future<Boolean> booleanFuture =
                accountingHandler.link(threadLatch, resultList, inputVo, invoiceModels, resultMsgs, newInputVo);
            LOGGER.info("本次执行结束,批次号:{}", syncSize);
            futures.add(booleanFuture);
            syncSize--;
        }


        // 设置超时时间为1分钟,超出执行时间中断程序并回滚
        try {
            // 等待所有子线程执行完毕
            boolean await = threadLatch.await(60, TimeUnit.SECONDS);
            if (!await) {
                rollBack.setRollBack(true);
            } else {
                // 查看执行情况,如果有存在需要回滚的线程,则全部回滚
                for (int i = 0; i < partitionList.size(); i++) {
                    Boolean result = resultList.take();
                    if (result) {
                        /** 有线程执行异常,需要回滚子线程. */
                        rollBack.setRollBack(true);
                    }
                }
            }
        } catch (InterruptedException e) {
            LOGGER.error("等待所有子线程执行完毕时,出现异常");
            rollBack.setRollBack(true);
        }


//后面根据 futures 及 rollBack.getRollBack() 可再次判断子线程执行情况,以处理后续逻辑

其中 accountingDocHandler.link()方法如下:

@Async("accountingLinkThreadPool")
    public Future<Boolean> link(CountDownLatch threadLatch,
                                BlockingDeque<Boolean> resultList,
                                ...
                                ) {

       //方法体

}

整体做法的优点在于可灵活控制每次处理的集合长度,及线程数量可控,可根据自己的业务场景酌情修改。。

需注意的一点是当有子线程执行失败时,回滚逻辑的处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值