使用线程池多线程并发提升处理业务速率

针对订单查询处理慢的问题,本文提出了两种优化策略。首先尝试将原始数据集拆分成小块进行处理,但效果不明显。接着引入线程池,通过分批并发执行任务进一步提升效率。每个线程处理一部分数据,最后汇总结果。这种方法显著提高了数据处理速度,是解决大数据量查询瓶颈的有效手段。
摘要由CSDN通过智能技术生成

业务场景:在查询订单的时候如何增加处理效率,处理的过程中代码对订单的数据进行了循环,查询数据库进行替换值。导致返回速率很低。

首先我的想法将最原始的数据集合进行拆分,分批处理。

集合拆分执行:

            //设置list切片大小
            int thresholdSize = 300;
            //查询出来的数据集合
            int rowNum = orderList.size();
            int number = rowNum % thresholdSize;
            List<Order> orderListAdd = new ArrayList<>();
                    for (int j = 0, startIndex = 0; ; j++) {
                        int splitIndex = thresholdSize * (j + 1);
                        if (startIndex == rowNum) {
                            break;
                        }
                        if (number > 0 && startIndex + number == rowNum) {
                            splitIndex = rowNum;
                        }
                        //处理数据的逻辑                                     
                        processOrder();
                        startIndex = splitIndex;
                    }

这样效率并没有很大的提升,在切片的基础上加上线程池多线程并发执行。

优化后:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;    

      
 //设置list切片大小
            int thresholdSize = 300;
            int rowNum = orderList.size();
            int number = rowNum % thresholdSize;
            List<Order> orderListAdd = new ArrayList<>();
            try {
                int taskSize = 5;
                // 创建一个线程池
                ExecutorService pool = Executors.newFixedThreadPool(taskSize);
                // 创建多个有返回值的任务
                List<Future> list = new ArrayList<Future>();
                    for (int j = 0, startIndex = 0; ; j++) {
                        int splitIndex = thresholdSize * (j + 1);
                        if (startIndex == rowNum) {
                            break;
                        }
                        if (number > 0 && startIndex + number == rowNum) {
                            splitIndex = rowNum;
                        }
                        Callable c = new OrderThread(orderList.subList(startIndex,splitIndex));
                        // 执行任务并获取Future对象
                        Future f = pool.submit(c);
                        list.add(f);

                        startIndex = splitIndex;
                    }
                pool.shutdown();
                // 获取所有并发任务的运行结果
                for (Future f : list) {
                    orderListAdd.addAll((Collection<? extends Order>) f.get());
                }

获得数据。值得注意的是,future模式获得数据,可以有两种形式,即无阻塞和阻塞,分别是isDone和get。上文写的get方法,将阻塞直到该线程运行结束,而future.isDone() return true或false 无阻塞。

 

线程内部:

import java.util.concurrent.Callable;

@Slf4j
public class OrderThread implements Callable<List<Order>> {

    private List<Order> orderList;
    

    public OrderThread(List<Order> orderList) {
        this.orderList = orderList;
    }

    @Override
    public List<Order> call() throws Exception {
        //处理逻辑
        return processOrder();
    }

}

如果要在线程中执行自己的方法可以参看原有文章:《关于异步线程无法使用@Autowired 自动注入》

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值