You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建CompletableFuture实现void方法异步执行与c()触发逻辑

用CompletableFuture实现你的异步执行需求

你的思路完全正确!CompletableFuture.anyOf()确实是实现“a()或b()任意一个完成后执行c()”的最优方案之一,接下来我会一步步教你怎么创建对应的CompletableFuture对象,以及完整的实现代码。

第一步:创建执行a()和b()的CompletableFuture

因为你的a()和b()是无参数、无返回值的void方法,最适合用CompletableFuture.runAsync()方法来创建异步任务,它会自动把任务提交到默认的ForkJoin线程池(或者你指定的自定义线程池)中并发执行。

方式1:使用默认线程池

// 异步执行a(),返回对应的CompletableFuture
CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> a());
// 异步执行b(),返回对应的CompletableFuture
CompletableFuture<Void> cf2 = CompletableFuture.runAsync(() -> b());

方式2:使用自定义线程池(生产环境推荐)

如果不想依赖默认线程池,你可以自己创建线程池来控制并发数,避免资源耗尽:

// 创建自定义线程池,比如固定2个线程的池
Executor customExecutor = Executors.newFixedThreadPool(2);

// 用自定义线程池执行a()和b()
CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> a(), customExecutor);
CompletableFuture<Void> cf2 = CompletableFuture.runAsync(() -> b(), customExecutor);

第二步:关联c()的执行逻辑

现在你有了cf1和cf2,接下来只需要用CompletableFuture.anyOf()监听这两个Future,只要其中任意一个完成,就触发c()的执行。这里有两种常见的实现方式:

方式1:异步触发c()(非阻塞,推荐)

这种方式不需要阻塞主线程,c()会在任意一个任务完成后自动异步执行:

// 监听cf1和cf2,任意一个完成后执行c()
CompletableFuture.anyOf(cf1, cf2).thenRun(() -> c());

// 如果需要等待所有任务(a()、b()、c())都完成后再继续主线程,可以用allOf+join
CompletableFuture<Void> cf3 = CompletableFuture.anyOf(cf1, cf2).thenRunAsync(() -> c());
CompletableFuture.allOf(cf1, cf2, cf3).join();

方式2:阻塞主线程后执行c()

如果你希望主线程等待任意一个任务完成后,再在主线程中执行c(),可以用join()阻塞:

// 阻塞主线程,直到cf1或cf2任意一个完成
CompletableFuture.anyOf(cf1, cf2).join();
// 此时执行c()
c();

完整示例代码

把上面的逻辑整合起来,完整的Java代码示例如下:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AsyncExample {
    public static void a() {
        System.out.println("方法a开始执行,线程:" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000); // 模拟耗时操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("方法a执行完成");
    }

    public static void b() {
        System.out.println("方法b开始执行,线程:" + Thread.currentThread().getName());
        try {
            Thread.sleep(5000); // 模拟耗时操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("方法b执行完成");
    }

    public static void c() {
        System.out.println("方法c开始执行,线程:" + Thread.currentThread().getName());
        // 模拟c()的操作
        System.out.println("方法c执行完成");
    }

    public static void main(String[] args) {
        // 创建自定义线程池
        Executor executor = Executors.newFixedThreadPool(2);

        // 创建异步任务
        CompletableFuture<Void> cf1 = CompletableFuture.runAsync(AsyncExample::a, executor);
        CompletableFuture<Void> cf2 = CompletableFuture.runAsync(AsyncExample::b, executor);

        // 任意一个任务完成后执行c()
        CompletableFuture<Void> cf3 = CompletableFuture.anyOf(cf1, cf2).thenRunAsync(AsyncExample::c, executor);

        // 等待所有任务完成
        CompletableFuture.allOf(cf1, cf2, cf3).join();

        // 关闭线程池
        ((java.util.concurrent.ThreadPoolExecutor) executor).shutdown();
        System.out.println("所有任务执行完毕");
    }
}

运行这个示例你会看到,a()和b()会立刻并发执行,当a()完成后(因为它耗时更短),c()会马上开始执行,而b()会继续执行直到完成。

内容的提问来源于stack exchange,提问作者user5992911

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:00:10