线程池实现批量插入

该博客探讨了在处理大量数据插入时如何利用并行流和线程池进行优化。通过设置线程池参数,如核心和最大线程数、存活时间和队列容量,实现了100个线程并发执行数据插入操作。为了避免数据丢失,计算了每个线程处理的数据量,并使用`Callable`和`Future`来跟踪每个线程的执行结果。在所有线程执行完毕后,进行了日志记录和线程池关闭操作。
摘要由CSDN通过智能技术生成
UserInfo currentUser = this.getCurrentUser();
        if (CollectionUtils.isNotEmpty(examCategoryFeeList)) {
            //用并行流处理插入数据基础字段,如果不处理,会包空指针
            ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
            threadPoolTaskExecutor.setCorePoolSize(100);
            threadPoolTaskExecutor.setMaxPoolSize(100);
            threadPoolTaskExecutor.setKeepAliveSeconds(3000);
            threadPoolTaskExecutor.setQueueCapacity(500);
            // 线程池需要初始化!
            threadPoolTaskExecutor.initialize();
            int nThreads = 100;
            int size = examCategoryFeeList.size();
            //每个线程执行的插入行数,如果不加1,会造成数据丢失:1537/100=15就会丢失数据,所以是(15+1)*100
            int threadSize = examCategoryFeeList.size() / nThreads + 1;
            List<Future<Integer>> futures = new ArrayList<>(nThreads);

            // 100个线程
            for (int i = 0; i < nThreads; i++) {
                //判断线程中分配到需要处理的数据  是否小于总数
                if (threadSize * (i + 1) <= size) {
                    //如果小于总数,直接截取,如果大于总数,会截取报错
                    final List<ExamCategoryFee> insertList = examCategoryFeeList.subList(threadSize * i, threadSize * (i + 1));
                    if (CollectionUtils.isNotEmpty(insertList)) {
                        Callable<Integer> callable = () -> {
                            examCategoryFeeSrv.saveAll(insertList);
                            return 1;
                        };
                        Future<Integer> submit = threadPoolTaskExecutor.submit(callable);
                        futures.add(submit);
                    }
                } else {
                    //如果大于总数,截取到末尾值=size
                    final List<ExamCategoryFee> insertList = examCategoryFeeList.subList(threadSize * i, size);
                    if (CollectionUtils.isNotEmpty(insertList)) {
                        Callable<Integer> callable = () -> {
                            examCategoryFeeSrv.saveAll(insertList);
                            return 1;
                        };
                        Future<Integer> submit = threadPoolTaskExecutor.submit(callable);
                        futures.add(submit);
                    }
                    break;
                }
            }
            if (CollectionUtils.isNotEmpty(futures)) {
                try {
                    //确保所有线程执行所返回值,也就是所有线程执行结束
                    for (Future<Integer> future : futures) {
                        this.logInfo("保存收费归类:future", JSON.toJSONString(future));
                        Integer integer = future.get();
                        if (1 != integer) {
                            this.logError("保存收费归类失败");
                        }
                    }
                    threadPoolTaskExecutor.shutdown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值