使用 CompletableFuture 实现异步编程
发布时间: 2024-01-10 01:21:09 阅读量: 12 订阅数: 20
# 1. 理解 CompletableFuture 异步编程
## 1.1 CompletableFuture 简介
在现代的应用开发中,异步编程已经成为一种常见的技术手段。CompletableFuture 是 Java 8 引入的一个强大的异步编程工具,提供了一种简洁方便的方式来处理异步任务和操作的结果。它可以在执行一个耗时操作时,不会阻塞其他线程,并且可以在任务完成后执行一系列的回调操作。
## 1.2 异步编程的优势
异步编程可以提高程序的响应性和并发能力,避免阻塞线程的情况,尤其在处理一些耗时的 I/O 操作或计算密集型任务时,可以显著提升应用的性能。使用 CompletableFuture 可以更加方便地进行异步编程,避免了传统线程操作的繁琐和复杂性。
## 1.3 CompletableFuture 与传统线程操作的区别
相比传统的线程操作,CompletableFuture 提供了更加强大和灵活的功能:
- CompletableFuture 可以支持异步任务的链式调用,避免了回调地狱的问题。
- CompletableFuture 提供了丰富的组合方法,可以方便地串行、并行地执行异步任务,并且在任务完成后可以进行结果的合并或转换操作。
- CompletableFuture 支持异常的处理和超时设置,可以更好地控制任务的执行流程。
下一章我们将深入研究 CompletableFuture 的基本使用。
# 2. 基本使用
### 2.1 创建 CompletableFuture 对象
在 CompletableFuture 中,可以通过以下几种方式来创建 CompletableFuture 对象:
- `CompletableFuture.runAsync()`:创建一个不返回结果的异步任务
- `CompletableFuture.supplyAsync()`:创建一个可以返回结果的异步任务
- `CompletableFuture.completedFuture()`:创建一个已经完成的 CompletableFuture 对象
```java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class CompletableFutureBasic {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 示例1:创建一个不返回结果的异步任务
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
// 异步任务的具体执行逻辑
System.out.println("任务一正在执行...");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务一执行完毕!");
});
// 示例2:创建一个可以返回结果的异步任务
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
// 异步任务的具体执行逻辑
System.out.println("任务二正在执行...");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务二执行完毕!");
return "任务二的结果";
});
// 示例3:创建一个已经完成的 CompletableFuture 对象
CompletableFuture<String> future3 = CompletableFuture.completedFuture("已完成的 CompletableFuture");
// 等待异步任务执行完毕并输出结果
future1.get();
future2.get();
System.out.println(future3.get());
}
}
```
代码说明:
- 示例1:通过 `CompletableFuture.runAsync()` 创建了一个不返回结果的异步任务,并在其中模拟了一个耗时操作。
- 示例2:通过 `CompletableFuture.supplyAsync()` 创建了一个可以返回结果的异步任务,并在其中模拟了一个耗时操作,并返回了一个结果。
- 示例3:通过 `CompletableFuture.completedFuture()` 创建了一个已经完成的 CompletableFuture 对象。
### 2.2 异步任务的执行与获取结果
在 CompletableFuture 中,异步任务的执行与获取结果可以通过以下几个方法来实现:
- `CompletableFuture.get()`:阻塞等待异步任务的完成,并获取结果
- `CompletableFuture.join()`:等待异步任务的完成,并获取结果(与 get() 方法的区别在于不抛出异常)
- `CompletableFuture.thenApply()`:对异步任务的结果进行转换处理
- `CompletableFuture.thenAccept()`:对异步任务的结果进行消费处理
- `CompletableFuture.thenRun()`:在异步任务完成后执行额外的操作
```java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class CompletableFutureExecution {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 示例1:获取异步任务的结果
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务一正在执行...");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务一执行完毕!");
return "任务一的结果";
});
System.out.println("任务一的结果为:" + future1.get());
// 示例2:对异步任务的结果进行转换处理
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务二正在执行...");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务二执行完毕!");
return "任务二的结果";
});
CompletableFuture<Integer> transformedFuture = future2.thenApply(result -> result.length());
System.out.println("任务二的长度为:" + transformedFuture.get());
// 示例3:对异步任务的结果进行消费处理
CompletableFuture<Void> future3 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务三正在执行...");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务三执行完毕!");
return "任务三的结果";
});
future3.thenAccept(result -> System.out.println("任务三的结果为:" + result));
// 示例4:在异步任务完成后执行额外的操作
CompletableFuture<Void> future4 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务四正在执行...");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务四执行完毕!");
return null;
});
future4.thenRun(() -> System.out.println("任务四执行完毕后的操作"));
}
}
```
代码说明:
- 示例1:通过 `CompletableFuture.get()` 来阻塞等待异步任务
0
0