CompletableFuture批量执行异步任务

分页批量执行异步任务

private List<Data> getDataListByBatch(DataQuery dataQuery, int totalSize) {
        List<Data> dataList= new CopyOnWriteArrayList<>();
        int totalPage = getTotalPage(totalSize);
        List<Integer> pageNumbers = getPageNumbers(totalPage);
        log.info("++++++++ getDataListByBatch() -> request: {}, totalSize: [{}], totalPage: [{}] ++++++++",
                JSON.toJSONString(dataQuery), totalSize, totalPage);
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
 
        CompletableFuture[] completableFutures = pageNumbers.stream()
                .map(pageNumber -> CompletableFuture
                        .supplyAsync(() -> {
                            PagePo<List<Data>> listPage = getListPagePo(dataQuery, pageNumber, MAX_BATCH_QUERY_SIZE);
                            return Objects.nonNull(listPage) ? listPage.getBodyList() : new ArrayList<Data>();
                        }, exportServiceExecutor)
                        .whenComplete((bodyList, throwable) -> {
                            if (!ObjectUtils.isEmpty(bodyList)) {
                                dataList.addAll(bodyList);
                            }
                        })).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(completableFutures).join();
        stopWatch.stop();
        log.info("++++++++ getDataListByBatch() -> stopWatch: {}ms ++++++++", stopWatch.getTotalTimeMillis());
        return dataList;
    }
 
    /**
     * 处理总页数
     *
     * @param totalSize
     * @return
     */
    private int getTotalPage(int totalSize) {
        return (totalSize % MAX_BATCH_QUERY_SIZE == 0)
                ? (totalSize / MAX_BATCH_QUERY_SIZE)
                : (totalSize / MAX_BATCH_QUERY_SIZE + 1);
    }
 
    /**
     * 获取页数
     *
     * @param totalPage
     * @return
     */
    private List<Integer> getPageNumbers(int totalPage) {
        int pageNumber = 1;
        List<Integer> pageNumbers = Lists.newArrayList();
        while (pageNumber <= totalPage) {
            pageNumbers.add(pageNumber++);
        }
        return pageNumbers;
    }
 

批量执行异步任务并获取返回结果代码 :

List<CompletableFuture<List<Object>>> completableFutureList = Lists.newArrayList();
	for (String consumerId : map.keySet()) {
	    CompletableFuture<List<Object>> rowsFuture = CompletableFuture.supplyAsync(() -> {//执行代码
	
	}, analysisExecutor);
	completableFutureList.add(rowsFuture);
}
CompletableFuture<Void> allFutures = CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[completableFutureList.size()]));
CompletableFuture<List<List<Object>>> listCompletableFuture = allFutures.thenApply(v -> completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList()));
List<List<Object>> rows = listCompletableFuture.get(20, TimeUnit.SECONDS);

`CompletableFuture` 是Java 8中引入的一个并行流处理库,用于异步编程,特别是处理串行和并发任务的组合。`supplyAsync` 方法用于将一个函数(Supplier)的结果异步地提供给未来(Future)。然而,`supplyAsync` 并不是总是能自动优化执行时间,优化主要取决于几个因素: 1. **CPU核心和线程池大小**:如果任务数量超过了系统的可用线程数,那么任务可能会被阻塞,直到有线程可用。如果线程池大小设置得当,可以最大化利用多核处理器的性能。 2. **任务并行性**:`supplyAsync` 默认使用ForkJoinPool来执行任务。如果任务本身是非阻塞的,且它们之间相互独立,那么可以受益于并行化。但如果任务之间存在依赖,过度并行可能反而降低效率。 3. **任务执行时间**:如果任务执行时间很短,那么即使在等待期间,其他任务也可能已经完成,导致整体执行时间并不明显优化。 4. **调度策略**:`supplyAsync` 中的任务会被添加到线程池的工作队列,调度策略(如优先级、时间片轮转等)会影响任务何时被执行。 5. **上下文切换开销**:频繁的上下文切换也会影响执行时间,特别是在任务间交互或IO密集型操作中。 如果你想优化`supplyAsync`的执行时间,可以考虑以下策略: - **调整线程池配置**:根据系统资源和预期负载动态调整线程池大小。 - **批处理**:对于大量的小任务,可以考虑使用`thenAcceptMany`或`thenApplyToLong/Double/Int`来批量提交。 - **优化任务**:减少不必要的同步和计算,使任务执行更快。 - **使用恰当的并发级别**:避免过度并发,尤其是在数据结构修改操作中,过多的并发可能导致数据一致性问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值