Java多线程数据分片处理

java对于数据量较大的数据插入处理或者业务逻辑调用多个远程接口出现性能瓶颈,如何用多线程优化

示例一、对于插入百万级批量数据的处理

1、基于java jdk并发包的实现数据分片处理

//线程池的定义
    private static final int corePoolSize = Runtime.getRuntime().availableProcessors();
    private static final int maximumPoolSize = corePoolSize * 4 + 1;
    private static final ExecutorService executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
            3L, TimeUnit.HOURS,
            new ArrayBlockingQueue<>(10000), new DefaultThreadFactory("async-data-worker"),
            new ThreadPoolExecutor.CallerRunsPolicy()); //业务数据分片
  List<T> datas= ...获取业务数据,若数据量过大,可以只获取id集分片,然后再查询整个model数据处理
              
  List<List<T>> partitions = Lists.partition(datas, 1000);

   List<CompletableFuture> futures = new ArrayList<>();
                    for (int i = 0; i < partitions.size(); i++) {
                        List<T> pDatas = partitions.get(i);
                        final int j =i;
                    futures.add(CompletableFuture.supplyAsync(() -> saveBatch(pDatas), executorService)                            //不需要处理返回值不需要执行thenAccept方法
                            .thenAccept((s) -> results.add(j)));
                }
//                CompletableFuture.allOf(futures.stream().toArray(CompletableFuture[]::new)).join();//不需要后续处理直接join等待所有子任务执行完成
                CompletableFuture.allOf(futures.stream().toArray(CompletableFuture[]::new)).thenRun(() -> {
                    results.forEach(item->{
                            log.info("批量数据执行结果={}",item);
                    });
                }).get();

从log打印的结果来看,整个返回的结果数据集是无序的

2、基于Google 的Guava的并发包实现数据分片处理

//业务数据分片
                List<T> datas= ...获取业务数据,若数据量过大,可以只获取id集分片,然后再查询整个model数据处理

                List<List<T>> partitions = Lists.partition(datas, 1000);
                // 定义监听执行服务
                ListeningExecutorService listeningExecutorService =
                        MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
                List<ListenableFuture<Integer>> listenableFutures = new ArrayList<>();
                for (int i = 0; i < partitions.size(); i++) {
                    List<T> pDatas= partitions.get(i);
                    final int j =i;
                    listenableFutures.add(listeningExecutorService.submit(()->{
                        saveBatch(pDatas);
                        return j;
                    }));
                }
                ListenableFuture<List<Integer>> listListenableFuture = Futures.allAsList(
                        Lists.newArrayList(listenableFutures));
                List<Integer> lists = listListenableFuture.get();
                lists.forEach(item->{
                    System.out.println(item);
                });

Guava的实现是要简洁一些的,从log打印的结果来看,整个返回的结果数据集是有序的
多接口并行调用用多线程优化也是同理

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值