相对于 JDK 1.5 出的 Future 类,进行业务编写的时,更像一把梭哈,都往一个方法里面写实现。
JDK 1.8 的 CompletableFuture 具有编排的功能,弥补 Future 类的缺点。
10 实例,带你了解 CompletableFuture 的使用。
🤔 场景一:在电商平台完成购买下订单支付功能
thenCompose 的使用
// 步骤一 获取商品
static CompletableFuture<Product> getProduct(Long productId) {
return CompletableFuture.supplyAsync(() -> productService(productId));
}
// 步骤二 生成订单
static CompletableFuture<Order> getOrder(Product product, Long userId) {
return CompletableFuture.supplyAsync(() -> orderService(product, userId));
}
// 步骤三 完成扣款
static CompletableFuture<Boolean> getPay(Order order) {
return CompletableFuture.supplyAsync(() -> payService(order));
}
// 进行组合
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 场景一 在电商平台完成购买下订单支付功能
Long productId = null;
Long userId = null;
ThenComposeTest thenComposeTest = new ThenComposeTest();
CompletableFuture<Boolean> isPay = getProduct(productId)
.thenCompose(product -> getOrder(product, userId))
.thenCompose(thenComposeTest::getPay);
System.err.println("支付状态:" + isPay.get());
}
场景一,使用的例子,真针对的是,每个 futurn 依赖于上一个 future 所返回的值,才能进行下一步计算。这种有点类似于开了一个主线程,主线程只做获取值,计算是通过 fork 一个子线程,丢给子线程来做计算。
静态方法 CompletableFuture.supplyAsync 完成的时候,会返回给定 supplier 所得的值(这个返回是 callback ,也可以看成阻塞的)。
之后,CompletableFuture.thenCompose 会将两个 CompletableFuture 的方法组合在一起,完成这一步骤的计算。
当计算的方法完成后,通过 CompletableFuture.get 阻塞当前的线程,直到提供此结果为止。
🚕 场景二:人口增长率计算
allOf 的使用
// 年末人口数
static CompletableFuture<Long> populationAfter() {
return CompletableFuture.supplyAsync(() -> 1411780000L);
}
// 年初人口数
static CompletableFuture<Long> populationBefore() {
return CompletableFuture.supplyAsync(() -> 1339720000L);
}
// 年平均人口
static CompletableFuture<Long> averageAnnualPopulation() {
return CompletableFuture.supplyAsync(() -> 1339405200L);
}
// 公式
static String formula(Long populationAfter, Long populationBefore, Long averageAnnualPopulation) {
// 人口增长率=(年末人口数-年初人口数)/年平均人口×1000‰
double populationGrowthRate = (populationAfter - populationBefore) / (averageAnnualPopulation * 1.000);
return String.format("%.3f", populationGrowthRate);
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
List<CompletableFuture<Long>> futures = Arrays
.asList(populationAfter(), populationBefore(), averageAnnualPopulation());
// 场景二 计算人口增长率
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
System.err.println(formula(futures.get(0).get(), futures.get(1).get(), futures.get(2).get()));
}
当我们需要并行处理多个任务时,通常要等待所有的任务执行完,然后才处理它们的结果。
CompletableFuture.allOf 就是允许等待所有的任务完成。
但是 CompletableFuture.allOf 返回的类型是 Void,因此我们需要手动从 CompletableFuture 获取结果,完成人口增长率计算。