CompletableFuture:Java 线程异步编排的魅力

引言

在现代软件开发中,异步编程已经成为处理高并发和高性能应用的重要技术。Java 8 引入了 CompletableFuture,这是一个强大的异步编程工具,可以帮助开发者更轻松地处理多线程编程中的异步任务。本文将详细介绍 CompletableFuture 的基本概念、常用方法和如何进行异步编排,帮助你在实际项目中更好地利用这一工具。

什么是 CompletableFuture?

CompletableFuture 是 java.util.concurrent 包下的一个类,实现了 Future 和 CompletionStage 接口。它提供了一种非常灵活的方式来处理异步任务,支持链式调用、组合多个异步任务、处理异步任务的结果和异常等多种操作。

基本概念

  • Future:一个代表异步计算结果的接口。它提供了一个方法 get() 来获取计算结果,如果计算结果尚未完成,调用 get() 会阻塞。
  • CompletionStage:一个表示异步计算阶段的接口。它允许你定义后续的计算阶段,这些阶段可以是另一个异步任务,也可以是同步任务。
  • CompletableFuture:一个具体的 Future 和 CompletionStage 实现类,提供了丰富的异步编程方法。

创建 CompletableFuture

CompletableFuture 提供了多种创建方法,可以用于启动异步任务。

1. 使用 runAsync 和 supplyAsync

  • runAsync(Runnable):用于创建一个不返回结果的异步任务。
  • supplyAsync(Supplier<T>):用于创建一个返回结果的异步任务。
// 不返回结果的异步任务
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
    System.out.println("Running async task without result");
});

// 返回结果的异步任务
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
    return "Hello, CompletableFuture!";
});

2. 使用 complete 方法

如果你已经有一个结果,可以直接完成 CompletableFuture

CompletableFuture<String> future3 = new CompletableFuture<>();
future3.complete("Task completed immediately");

异步任务的链式调用

CompletableFuture 支持链式调用,可以将多个异步任务组合成一个任务流。

1. thenApply:处理结果

thenApply 方法用于对前一个任务的结果进行处理,并返回一个新的结果。

CompletableFuture<String> future4 = future2.thenApply(result -> {
    return result.toUpperCase();
});

future4.thenAccept(System.out::println); // 输出: HELLO, COMPLETABLEFUTURE!

2. thenAccept:消费结果

thenAccept 方法用于消费前一个任务的结果,不返回新的结果。

future2.thenAccept(result -> {
    System.out.println("Result: " + result);
});

扫描二维码关注公众号,回复: 17588187 查看本文章

3. thenRun:执行后续动作

thenRun 方法用于在前一个任务完成后执行一个无参数的动作,不返回新的结果。

future2.thenRun(() -> {
    System.out.println("Task completed");
});

组合多个异步任务

CompletableFuture 还提供了多种方法来组合多个异步任务。

1. thenCompose:组合两个异步任务

thenCompose 方法用于将两个异步任务组合在一起,前一个任务的结果作为后一个任务的输入。

CompletableFuture<String> future5 = future2.thenCompose(result -> {
    return CompletableFuture.supplyAsync(() -> {
        return result + " - Extended";
    });
});

future5.thenAccept(System.out::println); // 输出: Hello, CompletableFuture! - Extended

2. thenCombine:组合两个异步任务

thenCombine 方法用于将两个异步任务的结果组合在一起,执行一个共同的处理函数。

CompletableFuture<String> future6 = CompletableFuture.supplyAsync(() -> {
    return "CompletableFuture-1";
});

CompletableFuture<String> future7 = CompletableFuture.supplyAsync(() -> {
    return "CompletableFuture-2";
});

CompletableFuture<String> future8 = future6.thenCombine(future7, (result1, result2) -> {
    return result1 + " " + result2;
});

future8.thenAccept(System.out::println); // 输出: CompletableFuture-1 CompletableFuture-2

处理异常

在异步任务中,处理异常是非常重要的。CompletableFuture 提供了 exceptionally 和 handle 方法来处理异常。

1. exceptionally:处理异常

exceptionally 方法用于处理前一个任务中抛出的异常,并返回一个默认的结果。

CompletableFuture<String> future9 = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("Task failed");
}).exceptionally(ex -> {
    return "Fallback result: " + ex.getMessage();
});

future9.thenAccept(System.out::println); // 输出: Fallback result: Task failed

2. handle:处理结果和异常

handle 方法用于处理前一个任务的结果或异常,并返回一个新的结果。

CompletableFuture<String> future10 = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("Task failed");
}).handle((result, ex) -> {
    if (ex != null) {
        return "Handle fallback: " + ex.getMessage();
    } else {
        return "Result: " + result;
    }
});

future10.thenAccept(System.out::println); // 输出: Handle fallback: Task failed

异步任务的并行执行

CompletableFuture 还支持并行执行多个任务,并在所有任务完成后进行处理。

1. allOf:等待所有任务完成

allOf 方法用于等待多个 CompletableFuture 对象完成,但不返回结果。

CompletableFuture<String> future11 = CompletableFuture.supplyAsync(() -> {
    return "Task 1";
});

CompletableFuture<String> future12 = CompletableFuture.supplyAsync(() -> {
    return "Task 2";
});

CompletableFuture<String> future13 = CompletableFuture.supplyAsync(() -> {
    return "Task 3";
});

CompletableFuture<Void> allFutures = CompletableFuture.allOf(future11, future12, future13);

allFutures.thenRun(() -> {
    System.out.println("All tasks are completed");
});

2. anyOf:等待任意一个任务完成

anyOf 方法用于等待多个 CompletableFuture 对象中的任意一个完成,并返回第一个完成的任务的结果。

CompletableFuture<String> future14 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "Task 1";
});

CompletableFuture<String> future15 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "Task 2";
});

CompletableFuture<String> anyFuture = CompletableFuture.anyOf(future14, future15);

anyFuture.thenAccept(result -> {
    System.out.println("First completed task: " + result);
}); // 输出: First completed task: Task 2

阻塞和非阻塞操作

CompletableFuture 支持阻塞和非阻塞操作,可以根据需要选择合适的方式。

1. 阻塞操作:get 方法

get 方法会阻塞当前线程,直到异步任务完成并返回结果。

try {
    String result = future2.get();
    System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

2. 非阻塞操作:thenApplythenAccept 和 thenRun

这些方法是非阻塞的,它们会在前一个任务完成后执行后续操作。

总结

CompletableFuture 是 Java 8 引入的一个强大工具,用于处理异步任务的编排。通过链式调用、组合多个异步任务以及异常处理等功能,CompletableFuture 能够帮助开发者更轻松地编写高性能、高并发的异步代码。


希望你喜欢这篇文章!请点关注和收藏吧。你的关注和收藏会是我努力更新的动力,祝关注和收藏的帅哥美女们今年都能暴富。如果有更多问题,欢迎随时提问

猜你喜欢

转载自blog.csdn.net/m0_64974617/article/details/144427842
今日推荐