相对于 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 获取结果,完成人口增长率计算。

Copyright © Sinsy Note 2021            updated 2021-08-10 00:20:51

results matching ""

    No results matching ""