CompletableFuture

创建线程方式

  1. 继承 Thread
  2. 实现 Runnable
  3. 实现 Callable,线程也能有返回值,必须搭配线程池或 FutureTask 使用

Callable 示例

FutureTask<Integer> futureTask = new FutureTask<>(() -> 123);
new Thread(futureTask).start();
System.out.println(futureTask.isDown()); // 线程是否运行结束
System.out.println(futureTask.get()); // get 会阻塞,等待线程运行结束

FutureTask 有缺陷,获取结果调用 get 方法会阻塞,并不知道什么时候能结束,倒是提供了一个 isDone 方法用来判断是否结束,但是在代码中死循环来判断任务是否结束,不优雅,并且也会增加 CPU 空转

CompletableFuture

  • 非阻塞获取线程处理结果:任务完成后执行回调函数获取结果而不是阻塞
  • 组合任务:使用 thenApplythenCombine 等方法将多个异步任务组合起来
  • 异常处理:提供了 handleexceptionally 方法来处理任务执行过程中可能发生的异常

常用方法

  1. supplyAsync:创建一个 CompletableFuture,有返回值

    CompletableFuture.supplyAsync(() -> {
        // 异步执行的任务
        return "Hello";
    });
    
  2. runAsync:创建一个 CompletableFuture,没有返回值

    CompletableFuture.runAsync(() -> {
        // 异步执行的任务,没有返回值
    });
    
  3. thenApply:处理前一个任务的结果,有返回值

    CompletableFuture.supplyAsync(() -> "Hello")
        .thenApply(result -> result + " World");
    
  4. thenAccept:处理前一个任务的结果,没有返回值

    CompletableFuture.supplyAsync(() -> "Hello")
        .thenAccept(result -> System.out.println(result));
    
  5. thenCombine:串联一个任务

    处理完后根据是否需要返回值,选择继续调用 thenApply 或 thenAccept

    CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 5);
    CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 10);
    
    future1.thenCombine(future2, (result1, result2) -> result1 + result2)
        .thenAccept(sum -> System.out.println("Sum: " + sum));
    
  6. allOf:等待所有任务完成

    thenCombine 要拿到 CompletableFuture 的结果,allOf 不需要

    有 CountDownLatch、Semaphore 的意味

    CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("Task 1"));
    CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> System.out.println("Task 2"));
    // 主线程此时阻塞住,join 和 get 作用相同,都是阻塞等待结果,区别是 join 不用捕获异常
    CompletableFuture.allOf(future1, future2).join(); 
    
  7. anyOf:看谁跑得快,用于处理多个任务中最先完成的一个任务的结果

    applyToEither 是两个任务中看谁跑得快,anyOf 是多个任务

    CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 1);
    CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 2);
    CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> 3);
    
    // 多个任务看谁跑得快
    CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2, future3);
    anyOf.thenAccept(result -> System.out.println("Any result: " + result));
    
    // 两个任务看谁跑得快
    CompletableFuture<Integer> resultFuture = future1
                .applyToEither(future2, result -> result * 10);
    
  8. exceptionally:捕获异常处理

    CompletableFuture.supplyAsync(() -> {
        if (true) throw new RuntimeException("Error");
        return "Success";
    }).exceptionally(ex -> {
        System.err.println("Exception: " + ex.getMessage());
        return "Fallback";
    });
    
    
  9. whenComplete:两个功能,1:任务完成后回调;2:捕获异常处理(exceptionally 的功能)

    CompletableFuture.supplyAsync(() -> {
        if (true) throw new RuntimeException("Something went wrong");
        return "Success";
    }).whenComplete((result, ex) -> { // 任务完成或异常走这里
        if (ex != null) { // 当没有异常
            System.err.println("Failed with exception: " + ex.getMessage());
        } else { // 当发生异常
            System.out.println("Completed successfully with result: " + result);
        }
    });
    
  10. handle:如果发生异常,可以不影响整个链的执行

    thenApply 示例,当其中一个任务异常,会印象整个链:

    public static void main(String[] args){
        CompletableFuture.supplyAsync(() -> 5) // 任务 1( 返回5 )
                .thenApply((v) -> v + 10) // 任务 2(返回 5+10 )
                .thenApply((v) -> v / 0) // 任务 3 (返回 15/0,报错 )
                .thenApply((v) -> v + 10) // 任务 4
                .whenComplete((r, e) -> {
                    System.out.println(r);
                });
    }
    // 打印 null,链中一个错误,会影响整个链
    

    handle 示例:

    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> 5) // 任务 1
                .thenApply((v) -> v / 0) // 任务 2(异常)
                .thenApply((v) -> v + 10) // 任务 3
                .handle((r, e) -> { // 前面的任务(任务1、任务2、任务3任意一个)是否有异常
                    if (e != null) {
                        return 0;
                    } else {
                        return r;
                    }
                })
                .thenApply((v) -> v + 10) // 任务 4
                .whenComplete((r, e) -> {
                    System.out.println(r);
                });
    }
    // 打印 10
    
posted @   CyrusHuang  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示