深入解析CompletableFuture的功能和用法

2023年 7月 14日 51.0k 0

1. CompletableFuture 简介

1.1 概述

CompletableFuture是 Java 8 中引入的一个类,它实现了CompletionStage接口,提供了一组丰富的方法来处理异步操作和多个任务的结果。它支持链式操作,可以方便地处理任务的依赖关系和结果转换。相比于传统的Future接口,CompletableFuture更加灵活和强大。

1.2 优势与特点

CompletableFuture的使用具有以下优势和特点:

  • 异步执行:CompletableFuture允许任务在后台线程中异步执行,不会阻塞主线程,提高了应用程序的响应性和性能。
  • 链式操作:通过CompletableFuture提供的方法,可以方便地对任务进行链式操作,构建复杂的任务依赖关系,实现高效的任务调度和执行。
  • 异常处理:CompletableFuture提供了丰富的异常处理方法,可以处理任务执行过程中可能发生的异常,并实现灵活的错误处理和回退机制。
  • 多任务组合:CompletableFuture支持多个任务的并发执行和结果组合。可以轻松地实现多任务并发处理的场景,提高应用程序的效率和并发性。

2. CompletableFuture 的基本用法

2.1 创建 CompletableFuture 对象

使用CompletableFuture创建异步任务非常简单。可以使用CompletableFuture.supplyAsync() 或CompletableFuture.runAsync() 方法来创建CompletableFuture对象。

2.1.1 使用CompletableFuture.supplyAsync() 方法

使用CompletableFuture.supplyAsync() 方法来创建 CompletableFuture 对象的示例。该方法用于执行具有返回值的任务,并在任务完成时返回结果。

CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    // 执行具有返回值的任务
    return "任务结果";
});

在上述示例中,我们使用CompletableFuture.supplyAsync() 方法创建一个具有返回值的 CompletableFuture 对象,任务会在默认的 ForkJoinPool 中异步执行。

2.1.2 使用CompletableFuture.runAsync() 方法

除了CompletableFuture.supplyAsync() 方法,CompletableFuture 还提供了CompletableFuture.runAsync() 方法用于执行没有返回值的任务。

CompletableFuture future = CompletableFuture.runAsync(() -> {
    // 执行没有返回值的任务
});

在上述示例中,我们使用CompletableFuture.runAsync() 方法创建一个没有返回值的 CompletableFuture 对象,任务会在默认的 ForkJoinPool 中异步执行。

2.1.3 指定自定义线程池

我们还可以通过指定自定义线程池来创建 CompletableFuture 对象,以满足特定的并发需求。

ExecutorService customExecutor = Executors.newFixedThreadPool(10);
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    // 执行任务的代码
}, customExecutor);

在上述示例中,我们通过Executors.newFixedThreadPool(10) 创建了一个固定大小为 10 的自定义线程池,并将其传递给CompletableFuture.supplyAsync() 方法来执行异步任务。

2.2 获取任务结果

获取CompletableFuture任务的结果有多种方式。最常用的方式是使用join() 方法阻塞当前线程,直到任务完成并返回结果。

2.2.1 使用join() 方法

join() 方法是 CompletableFuture 类提供的一种获取任务结果的方式,它会阻塞当前线程,直到任务完成并返回结果。

CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    // 执行任务的代码
    return "任务结果";
});
​
String result = future.join();

在上述示例中,我们使用join() 方法获取任务的结果,并将结果赋值给result变量。如果任务还未完成,join() 方法会阻塞当前线程,直到任务完成。

join() 方法和get() 方法非常相似,但join() 方法不会抛出InterruptedException和ExecutionException异常,而是将异常包装在CompletionException中抛出。因此,它更适合在 Lambda 表达式或流式操作中使用。

2.2.2 使用get() 方法

get() 方法也是 CompletableFuture 类提供的一种获取任务结果的方式,它会阻塞当前线程,直到任务完成并返回结果。与join() 方法不同的是,get() 方法会抛出InterruptedException和ExecutionException异常,需要进行异常处理。

CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    // 执行任务的代码
    return "任务结果";
});
​
try {
    String result = future.get();
} catch (InterruptedException | ExecutionException e) {
    // 异常处理逻辑
}

在上述示例中,我们使用get() 方法获取任务的结果,并在可能抛出异常的情况下进行异常处理。如果任务还未完成,get() 方法会阻塞当前线程,直到任务完成。

get() 方法的异常处理较为繁琐,需要捕获InterruptedException和ExecutionException异常,并进行相应的处理。因此,在 Lambda 表达式或流式操作中,推荐使用join() 方法。

2.3 异步回调方法

CompletableFuture 提供了一系列方法来处理任务的完成事件,实现异步回调。我们将逐一介绍这些方法的区别和用法。

thenApply()

方法签名:thenApply(Function... cfs)

  • 输入参数:多个 CompletableFuture 对象。
  • 返回值:CompletableFuture,没有返回值。
  • 功能:等待所有给定的 CompletableFuture 对象都完成,返回一个新的 CompletableFuture 对象。
CompletableFuture future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture future2 = CompletableFuture.supplyAsync(() -> 20);

CompletableFuture allFutures = CompletableFuture.allOf(future1, future2);

在上述示例中,我们使用 allOf()方法等待所有的 CompletableFuture 对象都完成,返回一个新的 CompletableFuture 对象。这样我们就可以在该对象上进行进一步的处理,例如获取各个 CompletableFuture 的结果。

3. 异常处理与错误处理

3.1 异常处理方法

CompletableFuture 提供了多种方法来处理异步任务执行中可能发生的异常。常用的方法有:

  • exceptionally(Function fn) :当 CompletableFuture 执行过程中发生异常时,使用指定的函数进行异常处理,并返回一个新的 CompletableFuture 对象,其中包含处理结果或默认值。
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("任务执行异常");
});

CompletableFuture handledFuture = future.exceptionally(ex -> {
    System.out.println("异常处理:" + ex.getMessage());
    return 0; // 默认值
});
  • handle(BiFunction

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论