Java多线程数据分片处理

Posted on   FLGB  阅读(842)  评论(0编辑  收藏  举报

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打印的结果来看,整个返回的结果数据集是有序的

多接口并行调用用多线程优化也是同理

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

随笔 - 205, 文章 - 1, 评论 - 7, 阅读 - 14万

Copyright © 2025 FLGB
Powered by .NET 9.0 on Kubernetes

点击右上角即可分享
微信分享提示