用多线程执行某一个业务逻辑,并且等待所有线程完成后在执行后面逻辑

使用场景

在我们的业务逻辑中,会有很多定时任务或者手动跑批任务,当我们有时候对时间效率要求比较高时,我们可能就需要用多线程来执行这个任务,假如我们的业务逻辑有顺序,需要执行A逻辑完成后才能执行B逻辑,那么这时候线程执行完还需要等待其他线程。

代码DEMO

具体的业务逻辑根据自己的业务逻辑来设计,我这里给出我的一种写法
public void updateAllPersonData() throws Exception {
		// 定时任务判断,防止前面一个没执行完,重叠跑,当然加锁也可以
        if (flag) {         
            logger.error("任务正在运行,请稍后...");
            return;
        }
        flag = true;
        try {
            // 查询所有对接系统的的人员信息
       		List<Map<String, String>> personArr = new ArrayList();
            // 每个线程处理10000个
            int cy = 10000;
            int allSize = personArr.size();
            logger.debug("返回的所有人员条数:" + allSize);
            // 此处开启一个线程池,根据自己的逻辑需要,我这里因为线程池是20的核心线程,我知道总的开启数没有20
            ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) SpringBeanUtil.getBean("dingTaskExecutor");
            // 这一步是为了线程等待其他线程完成
            int threadNum = allSize%cy >0?allSize/cy +1:allSize/cy ;
            // CountDownLatch 给一个计数,执行完一个线程后-1,直到为0,则可以继续向下执行
            CountDownLatch attendDownLatch = new CountDownLatch(threadNum);
            for (int i=0; i<threadNum; i++) {
                int endSize = (i+1) * cy ;
                if (endSize > allSize) {
                    endSize = allSize;
                }
                List<Map<String, String>> thisList = personArr.subList(i*1000, endSize);
                taskExecutor.execute(new SyncShrPersonRunner(thisList, attendDownLatch));
            }
            // CountDownLatch 给一个计数,执行完一个线程后-1,直到为0,则可以继续向下执行
            attendDownLatch.await(6, TimeUnit.HOURS);
            // 执行后面逻辑。。。。。
            logger.debug("同步全量人员数据结束");
        }catch (Exception e) {
            logger.error("同步全量人员数据异常", e);
        } finally {
            flag = false;
        }
    }
class SyncShrPersonRunner implements Runnable {
    private final List<Map<String, String>> personList;
    private final SysQuartzJobContext context;
    private final CountDownLatch countDownLatch;
    public SyncShrPersonRunner(List<Map<String, String>> personList, CountDownLatch countDownLatch) {
        this.personList = personList;
        this.context = context;
        this.countDownLatch = countDownLatch;
    }
    @Override
    public void run() {
        try{
            for (Map<String, String> map : personList) {
                // 处理每个用户 TODO          
            }
        } catch (Exception e) { 
            logger.error("更新异常:", e);
        } finally {
        	// 当前线程执行完计数器-1
            countDownLatch.countDown();
        }
    }
}

结语

这是一个小小的demo,希望可以帮助到有需要的人,我也是刚好有这个场景,多以记录一下。代码删除了一些业务逻辑,如有报错请自行补充完整。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值