Fork me on GitHub

Java异步编程CompletableFuture

1. 基本概念

1.1. 是什么

  • Java8引入的异步编程工具、支持非阻塞、链式调用、组合异步任务
  • 继承自Future,扩展CompletionStage接口

1.2. 解决什么问题

  • 传统的Future的局限性(阻塞获取结果、无法手动完成、组合能力差)
  • 简化异步编程,避免回调地狱

1.3. 核心接口

  • CompletiongStage:异步的某个节点,可以与其他阶段组合

2.实用总结

2.1.创建

  • 1.创建 CompletableFuture对象
//异步运行一个任务使用CompletableFuture.runAsync方法 没有返回值
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("Hello CompletableFuture!");
});
//2.获取结果
CompletableFuture<String> futureWithStringResult = CompletableFuture.supplyAsync(() -> {
// 异步运行一个任务并返回结果使用CompletableFuture.supplyAsync方法
return "Hello CompletableFuture!";
});
try {
System.out.println("result from futureWithStringResult: " + futureWithStringResult.get());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}

  • 2.同步运行一个任务 CompletableFuture.completedFuture
CompletableFuture<String> completableFuture = CompletableFuture.completedFuture("completableFuture");
try {
System.out.println(completableFuture.get());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}

  • 3.链式调用

    • thenApply():当CompletableFuture完成时,应用一个函数到结果上
    CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> "Hello").thenApply(result -> result + " World");
    try {
    System.out.println(stringCompletableFuture.get());
    } catch (InterruptedException | ExecutionException e) {
    throw new RuntimeException(e);
    }

    • thenAccept():当CompletableFuture完成时,消费结果
    CompletableFuture.supplyAsync(()->"Hello").thenAccept(System.out::println);

    • thenRun():当CompletableFuture完成时,运行一个动作
    CompletableFuture.supplyAsync(() -> "Hello").thenRun(() -> System.out.println("Completed!"));

  • 3.组合CompletableFuture

    • thenCombine():组合两个CompletableFuture
    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
    CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Word");
    future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2).thenAccept(System.out::println);
    //future1.thenCombineAsync(future2, (s1, s2) -> s1 + " " + s2).thenAccept(System.out::println);

    • threComose():组合两个CompletableFuture,当第一个完成时,是用其结果来创建第二个CompletableFuture
    CompletableFuture.supplyAsync(() -> "Hello").thenCompose(result -> CompletableFuture.supplyAsync(() -> result + " World by thenCompose")).thenAccept(System.out::println);
    //CompletableFuture.supplyAsync(() -> "Hello").thenComposeAsync(result -> CompletableFuture.supplyAsync(() -> result + " World by thenCompose")).thenAccept(System.out::println);

  • 4.异常处理

    • exceptionally():当CompletableFuture完成时,如果内部放生异常,提供一个备用的结果
    CompletableFuture<String> exceptionally = CompletableFuture.supplyAsync(() -> {
    if (true) {
    throw new RuntimeException("Something went wrong!");
    }
    return "Hello";
    }).exceptionally(e -> "Error" + e.getMessage());
    try {
    System.out.println(exceptionally.get());
    } catch (InterruptedException | ExecutionException e) {
    throw new RuntimeException(e);
    }

    • handle():当CompletableFuture完成时,无论是否发生异常,都应用一个函数到结果或者异常上
    CompletableFuture<String> handle = CompletableFuture.supplyAsync(() -> {
    if (true) {
    throw new RuntimeException("Something went wrong!");
    }
    return "Hello";
    }).handle((result, e) -> {
    if (e != null) {
    return "Handle Error" + e.getMessage();
    }
    return result;
    });
    try {
    System.out.println(handle.get());
    } catch (ExecutionException | InterruptedException e) {
    throw new RuntimeException(e);
    }

  • 5.等待完成

    • join()阻塞当前想成,直到CompletableFuture完成,并返回结果,如果发生异常,则抛出CompletionException异常
    //单个join
    String join = CompletableFuture.supplyAsync(() -> "Hello").join();
    System.out.println(join);
    //多个join
    System.out.println("multiple join");
    List<CompletableFuture<String>> completableFutures = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
    final int index = i;
    completableFutures.add(CompletableFuture.supplyAsync(() -> {
    // 业务处理
    return "Hello " + index;
    }));
    }
    completableFutures.stream().map(CompletableFuture::join).forEach(System.out::println);
    System.out.println("completed!");

    • get():与join类似,但会抛出InterruptedException和ExecuteException
    System.out.println("single get");
    try {
    String s = CompletableFuture.supplyAsync(() -> "Hello").get();
    System.out.println(s);
    } catch (InterruptedException | ExecutionException e) {
    throw new RuntimeException(e);
    }
    System.out.println("multiple get");
    List<CompletableFuture<String>> completableFutures = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
    final int index = i;
    completableFutures.add(CompletableFuture.supplyAsync(() -> "Hello " + index));
    }
    completableFutures.stream().map(item-> {
    try {
    return item.get();
    } catch (InterruptedException | ExecutionException e) {
    throw new RuntimeException(e);
    }
    }).forEach(System.out::println);
    System.out.println("completed!");

  • 取消任务

    • cancel():尝试取消任务的执行
    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    try {
    // 模拟业务操作
    Thread.sleep(3 * 1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    return "Hello";
    });
    future.handle((result,e)->{
    if(e!=null){
    e.printStackTrace();
    }
    return result;
    });
    boolean canceled = future.cancel(true);
    System.out.println(canceled);
    try {
    Thread.sleep(10*1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }


    以上就是CompleteFuture常用的一些方法

posted @   黄高林  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示