肥仔教程网

SEO 优化与 Web 开发技术学习分享平台

什么是Java的CompletableFuture?详细介绍一下?

CompletableFuture在JDK1.8之后引入的一个用来处理异步编程的类,是属于java.util.concurrent 包中Future接口的扩展类,主要是用来进行异步计算、非阻塞操作、任务组合操作等。简化了异步任务操作的复杂性,提供了基于流式调用的API,方便了开发者可以通过更加直观的方式来编写阻塞式的代码实现。

基本概念

CompletableFuture是一个表示未来某个时间点会完成的计算结果的对象。它不同于Future接口的只能阻塞等待结果的返回,在CompletableFuture中提供了很多在任务完成后进行的操作方法。通过链式调用这些方法将多个异步任务组合在一起,从而支持多步骤的异步编程。

常用功能

创建CompletableFuture

可以通过
CompletableFuture.completedFuture(value) 方法创建一个立即完成的 CompletableFuture。如下所示,
直接创建完成状态的CompletableFuture。

CompletableFuture<String> future = CompletableFuture.completedFuture("Hello");

除了上面的方法还可以通过异步的方式来创建,如下所示是两种异步创建的方法。

  • CompletableFuture.runAsync():执行一个没有返回值的异步任务。
  • CompletableFuture.supplyAsync():执行一个有返回值的异步任务。
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
    // 执行一些任务
});

CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
    // 返回任务结果
    return "Task Result";
});

链式调用和回调

CompletableFuture提供了通过链式调用的方式来处理异步操作的方式,这样的话可以避免了嵌套回调带来的代码复杂性,如下所示。

thenApply方法会在计算结果之上继续调用一个函数然后返回一个新的CompletableFuture,如下所示。

future.thenApply(result -> result + " World");

thenAccept方法在计算结果上应用一个Consumer,但不返回新的CompletableFuture。

future.thenAccept(result -> System.out.println(result));

thenRun在计算完成后运行一个任务,但不会使用计算结果,如下所示。

future.thenRun(() -> System.out.println("Task completed."));

组合多个CompletableFuture

thenCompose方法,可以将两个异步任务串行化,第二个任务依赖于第一个任务的结果。常用于任务之间存在依赖关系的情况,如下所示。

CompletableFuture<String> combinedFuture = future.thenCompose(result ->
    CompletableFuture.supplyAsync(() -> result + " Combined"));

thenCombine方法,是主要将两个独立的CompletableFuture的结果进行合并,如下所示。

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
CompletableFuture<String> combined = future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2);

allOfanyOf

  • allOf:等待多个 CompletableFuture 全部完成。
  • anyOf:只要其中任意一个 CompletableFuture 完成即可。
CompletableFuture<Void> all = CompletableFuture.allOf(future1, future2);
CompletableFuture<Object> any = CompletableFuture.anyOf(future1, future2);

异常处理

CompletableFuture 提供了多种异常处理方法,来捕获并处理异步任务中的异常,其中比较常见的方式有如下几种。

  • exceptionally:在出现异常时执行补救措施。
future.exceptionally(ex -> {
    System.out.println("Exception: " + ex.getMessage());
    return "Fallback result";
});
  • handle:无论是否出现异常,都会执行该回调。可以对结果或异常进行处理。
future.handle((result, ex) -> {
    if (ex != null) {
        System.out.println("Exception: " + ex.getMessage());
        return "Fallback result";
    }
    return result;
});

主要优势

CompletableFuture提供了异步计算的方式,通过链式调用,使代码更简洁、易读但是多个依赖关系复杂的CompletableFuture链式操作时,可能会发生死锁,需要谨慎设计依赖关系。

CompletableFuture内部建立了很多的异常处理机制使得异常处理变得更加简单。同时可以轻松地将多个任务串联、并行处理,极大提高了处理复杂任务的能力,但是需要注意异步操作较多时要小心内存和线程资源的使用,避免过度使用异步操作。

示例

展示如何通过CompletableFuture实现任务组合和异常处理,如下所示。

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    if (Math.random() > 0.5) throw new RuntimeException("Oops!");
    return "Hello";
}).thenApply(result -> result + " World")
  .exceptionally(ex -> "Recovered from error")
  .thenCombine(CompletableFuture.supplyAsync(() -> " CompletableFuture"), (result1, result2) -> result1 + result2);

future.thenAccept(System.out::println);


总结

总结而言,CompletableFuture 是 Java 异步编程中强大且灵活的工具,适用于各种复杂任务的组合与管理,同时它简化了传统回调的层次结构和异常处理。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言