使用多线程处理作业,处理完毕然后插入数据结果(线程池)

此处我用的方案是先用多线程处理数据,处理完毕后将一共的数据分批次(每次500条,看数据结果每条的大小,mybatis使用foreach整体插入数据有上限,根据实际情况来定)向数据库里插入结果。

1.自己项目的话可以定义一个线程池的工具类,如果只想用在某个地方的话可以直接声明

       此处我用的工具类,且只用的定长线程池,阿里文档不推荐,可以根据任务适当调整:

public class PoolUnit {
    private static final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);

    public static ExecutorService getInstance() {
        return executorService;
    }
  
}

        解释一下为什么线程数要用:Runtime.getRuntime().availableProcessors() * 2

        Runtime.getRuntime().availableProcessors()返回的是CPU的处理器数量

         Runtime.getRuntime().availableProcessors()获取的是什么? - 知乎

2.处理作业

public class Test{



public void jobProcessingAndSaveResult(){

//处理数据的结果集
List<ResultEntity> future = new ArrayList<>();

//DataEntities是要处理的数据
for (DataEntity entity : DataEntities) {
    Callable<List<ResultEntity>> result = new Callable<List<ResultEntity>>() {
      @Override
      public List<ResultEntity> call() throws Exception {
               return jobProcessing();
      }
    };

  //将每次循环产生的结果统一添加到future集合内
  future.addAll(PoolUnit.getInstance().submit(result).get());
 }

}





//处理业务代码,返回值就是想要插入数据库的结果实体类
public List<ResultEntity> jobProcessing(){
    //此处是业务逻辑代码,想要怎样处理的,但不包含将结果插入数据库
}

}

3.插入结果

int runSize = 500;
int taskSize = (future.size() % runSize) == 0 ? (future.size() / runSize) : (future.size() / runSize) + 1;
int fromIndex, toIndex;
for (int n = 0; n < taskSize; n++) {
    fromIndex = n * runSize;
    //确保取最后数据正确
    toIndex = Math.min(future.size(), fromIndex + runSize);
    List<ResultEntity> subData = future.subList(fromIndex, toIndex);
    ResultService.insertResultBatch(subData);
}
                    

插入结果这部分是需要放在jobProcessingAndSaveResult方法内的,insertResultBatch是通过使用mybatis中的foreach插入的,因为500条数据插入只请求一次数据库,时间方面会节省很多。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值