多线程处理大数据量查询

最近在实现一个导入功能,数据量在5w左右,后续会持续增长,使用的是easyExcel,读取文件性能较好,但因为每条数据都要做复杂的数据校验,导致整体响应时间在三四十分钟,虽然说导入不是直接和用户交互,但现在数据量不算很大的情况下,这个响应时间还是需要优化的,读取文件速度在几秒以内,主要是在数据校验这块,所以就使用了多线程去工作。

主要代码:

import java.util.concurrent.*;
public class Test{
private static final int threadNum = Runtime.getRuntime().availableProcessors()*2;// 获取cpu核数
public void syncData(List<NewRegionReq> regionList) throws ExecutionException, InterruptedException {
        /**
         * 多线程分析数据
         */
        List<Future> list = new ArrayList<>();
        ExecutorService executor = Executors.newFixedThreadPool(threadNum);
        int num = (regionList.size() / threadNum) + 1;  //计算每个线程需要处理的记录数
        for (int j = 0; j < threadNum; j++) {
            //读取数据的起始位置
            int startNum = j * num;
            //读取数据的结束位置
            int endNum = startNum + num;
            //添加任务
            Callable<String> task = new ThredQuery(regionList, startNum, endNum);
            Future f = executor.submit(task);
            //接受返回结果
            list.add(f);
        }
        // 关闭线程池
        executor.shutdown();
        for (Future f : list) {
            // 从Future对象上获取任务的返回值,并输出到控制台
            System.out.println(f.get().toString()); //OPTION + return 抛异常
        }
        newRegionMapper.save(regionList);
        log.info("共导入数据 {} 行", regionList.size());
    }

class ThredQuery implements Callable<String> {
        private List<NewRegionReq> regionList;
        private int startNum;
        private int endNum;

        public ThredQuery(List<NewRegionReq> regionList, int startNum, int endNum) {
            this.regionList = regionList;
            this.startNum = startNum;
            this.endNum = endNum;
            //System.out.println(startNum + "\t" + endNum);
        }

        @Override
        public String call() {
            for (int i = startNum; i < endNum; i++) {
            	//自己的业务逻辑
                //if (i < regionList.size()) {
               //}
            }
            return "成功";
        }
    }
}

思路:
1:先计算出查询总量,根据服务器的cpu核数,求每个线程应处理的条数
2.使用Callable返回结果,然后聚合数据,最后处理。

这里有个问题就是线程池合理的线程数你是如何考虑的?这也是之前面试遇到的一个题:

1.先看下机器的CPU核数,然后在设定具体参数:

System.out.println(Runtime.getRuntime().availableProcessors());

即CPU核数 = Runtime.getRuntime().availableProcessors()

2.分析下线程池处理的程序是CPU密集型,还是IO密集型

CPU密集型:核心线程数 = CPU核数 + 1

IO密集型:核心线程数 = CPU核数 * 2

注:IO密集型(某大厂实践经验)

   核心线程数 = CPU核数 / (1-阻塞系数)     例如阻塞系数 0.8,CPU核数为4

   则核心线程数为20

|本期文章就到这里了,我是梦辰,可以微信搜一搜「 梦辰的架构笔记 」公众号,保证是干货!!!欢迎大家和我交流。|
|----------------------------------------------------------|–|

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值