【JAVA】主线程抛出采用线程池时子线程异常错误

本文探讨了在处理大量数据时,如何使用单线程读取表A并利用多线程更新其他表数据。通过示例代码展示了如何设置线程池和异常处理器,确保线程异常能被主线程捕获。最后,提出了通过传递异常列表来监控子线程状态的方法,确保所有任务完成后检查并抛出异常。
摘要由CSDN通过智能技术生成

前言:

有个批量需求,想读一张表A数据,用此表数据维护其他表数据。
因数据量可能很大,采用了单线程读表A,多线程处理其他表数据。

遇到问题

不做处理时,子线程异常是不影响主线程的。
参考了很多网上代码,如:

   ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100,
                30L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), namedThreadFactory){
            protected void afterExecute(Runnable r,Throwable t) {
                super.afterExecute(r,t);
                printException(r,t);
            }
        };

private static void printException(Runnable r,Throwable t) {
    throw new RuntimeException("error");
}

 Thread.setDefaultUncaughtExceptionHandler((t,e) -> {
            throw new RuntimeException("error");
        });

都无实现主线程异常。

实现

通过传参到线程池中,判断线程结果,给到线程池中。最后判断参数结果。

 List<Exception> threadException = new ArrayList<>();
        do {
            dataList = queryClByPage(maxAcctId,1000);
            // 查询无数据 等待10秒
            if (CollUtil.isEmpty(dataList)) {
                break;
            }
            maxAcctId = dataList.get(0).getId();

            List<List<T>> split = CollectionUtil.split(dataList, 100));
            for (List<T> batchData : split) {
                // 添加任务到队列
                threadPoolExecutor.execute(batchData,new DataListProcessTask(threadException));
            }
        }
        while (1000 == dataList.size());
        //不在接收新的任务
        threadPoolExecutor.shutdown();
        try {
            // 等待所有线程执行完毕
            threadPoolExecutor.awaitTermination(Long.MAX_VALUE,TimeUnit.NANOSECONDS);
            log.info("任务完成,线程池关闭成功");
        } catch (InterruptedException e) {
            // no thing
            log.info("任务完成,线程池关闭失败");
            threadPoolExecutor.shutdownNow();
        }
        if (!threadException.isEmpty()) {
            throw new RuntimeException("error");
        }

线程:

public static class DataListProcessTask<T> implements Runnable {
        private final List<T> batchDataList;
        private List<Exception> threadException;
        AppLogger log = AppLoggerFactory.getLogger(getClass());

        public DataListProcessTask(List<T> batchDataList,List<Exception> threadException) {
        	this.batchDataList = batchDataList;
            this.threadException = threadException;
        }

        @Override
        public void run() {
            // 批量处理
            try {
                //切数据源
                function(batchDataList);
            } catch (Exception e) {
                this.threadException.add(e);
            }
        }

      
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值