Java中CompletableFuture全面教程

Java 8 中 CompletableFuture 的引入标志着处理异步操作的重大飞跃。CompletableFuture 是一个强大而灵活的类,它有利于并发编程,使开发人员更容易编写高效且可扩展的代码。

在这篇博文中,我们将深入研究 CompletableFuture 的理论方面,探索其主要功能、方法和用例。

了解 CompletableFuture:
从本质上讲,CompletableFuture 是一个表示异步计算的未来结果的类。它扩展了 CompletableFuture 类,引入了链接和组合多个异步操作的方法。CompletableFuture 支持广泛的操作,包括组合多个 CompletableFuture、应用转换、处理错误等等。


CompletableFuture特点:

1. 异步编程简介:
   异步编程是一种允许任务独立运行、释放资源并提高系统整体效率的范例。CompletableFuture 旨在处理异步计算,提供更直观、更简化的并发操作方式。

2. 创建CompletableFuture:
   CompletableFuture 可以通过多种方式创建,使开发人员能够灵活地处理异步任务。无论是使用“CompletableFuture.runAsync()”、“CompletableFuture.supplyAsync()”还是手动实例化,每种方法都根据任务的要求提供不同的方法。

3. 组合CompletableFutures:
   CompletableFuture 支持多个异步任务的组合,使开发人员能够创建复杂的工作流程。`thenApply()`、`thenAccept()` 和 `thenCompose()` 等方法促进了操作的链接,从而允许异步活动的无缝协调。

4、异常处理:
   CompletableFuture 提供了强大的机制来处理异步代码中的异常。“exceptionally()”和“handle()”方法允许开发人员优雅地管理错误,确保应用程序即使面对意外问题也能保持弹性。

5. 异步计算和回调:
   CompletableFuture 通过“thenApplyAsync()”、“thenAcceptAsync()”和“thenComposeAsync()”等方法支持回调的概念。这允许开发人员指定任务完成后应如何继续,确保高效且响应迅速的代码执行。

6. 超时和完成检查:
   CompletableFuture 提供了处理超时和检查完成状态的机制。“completeOnTimeout()”方法和“isDone()”方法使开发人员能够根据时间限制和任务完成状态控制执行流程。

7. 组合多个CompletableFutures:
   通过“allOf()”和“anyOf()”方法,CompletableFuture 简化了组合多个异步任务结果的过程。无论是等待所有任务完成还是仅等待一个任务完成,这些方法都增强了并发编程的表现力。

CompletableFuture 的内部组件:
1.ForkJoinPool:
   CompletableFuture 依赖于 Java 7 中引入的 ForkJoinPool 来并行执行任务。它有效地管理工作线程并提供并行工作的机制。CompletableFuture 使用该池来执行异步任务,确保最佳的资源利用率。

2、执行器:
   CompletableFuture 允许您指定一个执行器来控制 CompletableFuture 完成其计算的线程。此功能使开发人员能够对线程管理和执行上下文进行细粒度控制。

3. 回调和组合器:
   CompletableFuture 使用回调和组合器来促进异步操作的组合。回调是在 CompletableFuture 成功或异常完成时执行的函数。另一方面,组合器是允许您组合多个 CompletableFutures、以无缝方式转换其结果或处理错误的方法。

CompletableFuture 的实际应用示例:
让我们通过一些示例来说明 CompletableFuture 的内部工作原理:

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

public class Main {
    public static void main(String[] args) {
        // Example 1: Simple CompletableFuture
        CompletableFuture<String> future =
                CompletableFuture.supplyAsync(() ->
"Hello")
                        .thenApplyAsync(s -> s +
" World");

       
// 示例 2:异常处理
        CompletableFuture<Object> exceptionFuture =
                CompletableFuture.supplyAsync(() -> {
                    throw new RuntimeException(
"Exception in CompletableFuture");
                }).exceptionally(ex ->
"Handled Exception: " + ex.getMessage());

       
// 例 3:组合可完成期货
        CompletableFuture<String> combineFutures =
                CompletableFuture.supplyAsync(() ->
"Hello")
                        .thenCombine(CompletableFuture.supplyAsync(() ->
" World"), (s1, s2) -> s1 + s2);

       
// 例 4:使用自定义执行器进行异步执行
        Executor customExecutor = Executors.newFixedThreadPool(5);
        CompletableFuture<String> asyncWithExecutor =
                CompletableFuture.supplyAsync(() ->
"Hello", customExecutor);

       
//例 5:通过回调应用转换
        CompletableFuture.supplyAsync(() ->
"Hello")
                .thenApplyAsync(s -> s +
" World")
                .thenAcceptAsync(System.out::println);
    }
}

CompletableFuture 的性能
在 Java 并发编程领域,CompletableFuture 已成为管理异步任务的强大工具。它提供了一种灵活且富有表现力的方式来处理并行执行,使其成为提高性能的关键角色。

1.并行执行:
   CompletableFuture 允许您轻松地表达并行性。通过利用“thenApplyAsync”和“thenComposeAsync”方法,您可以轻松并行化独立任务,从而提高性能。

CompletableFuture< String > future1 = CompletableFuture.supplyAsync(() -> "Hello" ); 
CompletableFuture< String > future2 = CompletableFuture.supplyAsync(() -> " World" ); 

CompletableFuture< String > linkedFuture = future1.thenCombine(future2, (s1, s2) -> s1 + s2);

2、异常处理:
   CompletableFuture 通过提供干净直观的方式来处理异常,从而简化了错误管理。在处理异步操作时,这可以使代码更加健壮和高性能。

CompletableFuture< Integer > future = CompletableFuture 
        .supplyAsync(() -> 10 / 0 ) 
        .exceptionally(ex -> 0 );

3. 组合多个期货:
   CompletableFuture 可以轻松组合多个异步操作。这在需要同时执行多个任务并将其结果组合起来的场景中尤其有用。

CompletableFuture< String > future1 = CompletableFuture.supplyAsync(() -> "Hello" ); 
CompletableFuture< String > future2 = CompletableFuture.supplyAsync(() ->
" World" ); 

CompletableFuture< String > linkedFuture = future1.thenCombine(future2, (s1, s2) -> s1 + s2);

4. 超时和完成政策:
   CompletableFuture 提供了“completeOnTimeout”和“orTimeout”等方法来有效地处理超时。这可以确保您的应用程序不会无限期地等待结果,从而有助于提高整体性能。

CompletableFuture< String > future = CompletableFuture 
        .supplyAsync(() -> PerformLengthyOperation()) 
        .completeOnTimeout( "默认结果" , 5 , TimeUnit.SECONDS);


让我们深入研究几个实际示例来说明 CompletableFuture 的性能优势。

1.并行数据处理:
   假设您有一个可以独立处理的任务列表。使用 CompletableFuture,您可以轻松并行处理,从而减少总体执行时间。

List< String > data = Arrays.asList( "任务1" , "任务2" , "任务3" , "任务4" ); 

List< CompletableFuture < String >> futures = data.stream() 
        .map(task -> CompletableFuture.supplyAsync(() -> processTask(task))) 
        .collect(Collectors.toList()); 

CompletableFuture< Void > allOf = CompletableFuture.allOf(futures.toArray( new CompletableFuture[ 0 ]));

2. 异步API调用:
   当处理多个外部API调用时,可以使用CompletableFuture来并发执行它们,从而显着加快整体响应时间。

CompletableFuture< String > result1 = CompletableFuture.supplyAsync(() -> callExternalAPI( "Endpoint1" )); 
CompletableFuture< String > result2 = CompletableFuture.supplyAsync(() -> callExternalAPI(
"Endpoint2" )); 

CompletableFuture<String> combinedResult = result1.thenCombine(result2, (r1, r2) -> r1 + r2);

结论
Java 中的 CompletableFuture 是一个用于处理异步操作的多功能且强大的工具。其性能优势与直观的语法和卓越的处理能力相结合,使其成为并发编程中的宝贵财富。

通过将 CompletableFuture 合并到您的代码库中,您可以充分利用并行性和异步执行的潜力,从而实现更快、更高效的应用程序。因此,请毫不犹豫地探索和利用 CompletableFuture 的功能来提升 Java 项目的性能。