【CompletableFuture 优化 顾客下单流程】

场景

以下是一个顾客下单的流程模拟:

1、获取基本产品信息(此处查询数据库)
2、获取每一个产品的价格(假设此处需要通过第三方服务平台进行实时定价,产品不同调用的平台亦不同,所有此处是挨个获取)
3、计算产品总价
4、获取用户余额(此处也是调取第三方服务,获取用户账户余额)
5、比对余额是否充足
6、如果余额充足则提示购买成功,并扣去花费,更新用户余额(此处也是调取第三方服务,更新用户账户余额)
7、返回是否购买成功

代码

public class App {


    public static void main(String[] args) throws Exception {
        App app = new App();
        // 1. 非并发查询
        app.searchProduct();
        // 2. CompletableFuture 优化
        app.searchProductByCompletableFuture();
    }


    public void searchProductByCompletableFuture() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        ExecutorService subExecutorService = Executors.newFixedThreadPool(5);
        try {
            long timeStart = System.currentTimeMillis();

            CompletableFuture<List<Product>> listCompletableFuture = CompletableFuture.supplyAsync(() -> {
                        try {
                            // 1.获取基本产品信息
                            return getProducts();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        return null;
                    }, executorService)
                    .whenComplete(new LogErrorAction<>("getProducts"))
                    .thenApply(productList -> {
                        // 2.并发获取每一个产品的价格
                        productList
                                .stream()
                                .forEach(product -> {
                                            BigDecimal realPrice = CompletableFuture
                                                    .supplyAsync(() -> getProductPrice(product), subExecutorService)
                                                    .join();
                                            product.setPrice(realPrice);
                                        }
                                );
                        return productList;
                    });

            //3.获取用户余额
            CompletableFuture<BigDecimal> userAccountCf = CompletableFuture.supplyAsync(() -> {
                try {
                    return getUserAccount();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            }, executorService).whenComplete(new LogErrorAction<>("getUserAccount"));

            // List<Product> allProduct = listCompletableFuture.join();
            // 同步阻塞获取所有数据结果
            CompletableFuture<Void> cf3 = CompletableFuture.allOf(userAccountCf, listCompletableFuture);
            cf3.thenAccept(v -> {
                //这里的join并不会阻塞,因为传给thenAccept的函数是在 cf 全部完成时,才会执行。
                List<Product> allProduct = listCompletableFuture.join();
                // 4、计算产品总价
                BigDecimal priceSum = allProduct.stream()
                        .map(Product::getPrice)
                        .reduce(new BigDecimal(0), BigDecimal::add);
                System.out.println("searchProductByCompletableFuture:产品总价:" + priceSum);
                Assert.assertEquals("2780", priceSum.toString());

                BigDecimal userAccount = userAccountCf.join();
                // 5、比对余额是否充足
                String result = "";
                if (userAccount.compareTo(priceSum) < 0) {
                    result = "余额不足,购买失败";
                } else {
                    result = "余额充足,购买成功";
                    // 6、更新用户的余额
                    BigDecimal left = userAccount.subtract(priceSum);
                    System.out.println("searchProductByCompletableFuture:用户购买后余额:" + left);
                    updateUserAccount(left);
                }
                System.out.println(result);
            });
            long timeUseMs = System.currentTimeMillis() - timeStart;
            System.out.println("searchProductByCompletableFuture:并发查询耗时:" + timeUseMs);
        } finally {
            executorService.shutdown();
            subExecutorService.shutdown();
        }
    }


 

    public void searchProduct() throws InterruptedException {
        long timeStart = System.currentTimeMillis();
        // 1、获取基本产品信息
        List<Product> productList = getProducts();
        // 2、获取每一个产品的价格
        for (Product product : productList) {
            product.setPrice(getProductPrice(product));
        }
        // 3、计算产品总价
        BigDecimal priceSum = productList.stream()
                .map(Product::getPrice)
                .reduce(new BigDecimal(0), BigDecimal::add);
        System.out.println("searchProduct: 产品总价:" + priceSum);
        Assert.assertEquals("2780", priceSum.toString());
        // 4、获取用户余额
        BigDecimal userAccount = getUserAccount();
        // 5、比对余额是否充足
        String result;
        if (userAccount.compareTo(priceSum) < 0) {
            result = "余额不足,购买失败";
        } else {
            result = "余额充足,购买成功";
            // 6、更新用户的余额
            BigDecimal left = userAccount.subtract(priceSum);
            System.out.println("searchProduct:  用户购买后余额:" + left);
            updateUserAccount(left);
        }
        System.out.println(result);
        long timeUseMs = System.currentTimeMillis() - timeStart;
        System.out.println("searchProduct: 非并发查询耗时:" + timeUseMs);
    }


    /**
     * 获取产品价格,模拟调用外部服务
     *
     * @param product 产品
     * @return 产品价格
     * @throws InterruptedException Exception
     */
    public BigDecimal getProductPrice(Product product) {
        // 模拟耗时查询——调用外部服务接口
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new BigDecimal(product.getId() * 10 + 233);
    }

    /**
     * 获取产品列表,模拟从数据库查询数据
     *
     * @return 产品列表
     * @throws InterruptedException Exception
     */
    public List<Product> getProducts() throws InterruptedException {
        List<Product> productList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Product product = new Product();
            product.setId((long) i);
            product.setName("product" + i);
            product.setCreateTime(new Date());
            productList.add(product);
        }
        // 模拟耗时查询
        Thread.sleep(1000);
        return productList;
    }

    /**
     * 获取用户的账户余额
     *
     * @return 账户余额
     * @throws InterruptedException Exception
     */
    public BigDecimal getUserAccount() throws InterruptedException {
        // 模拟耗时查询 —— 调用外部服务获取当前用户余额
        Thread.sleep(500);
        return new BigDecimal(3000);
    }

    /**
     * 更新用户的账户余额
     *
     * @param left 账户余额
     * @throws InterruptedException Exception
     */
    public boolean updateUserAccount(BigDecimal left) {
        // 模拟耗时操作 —— 调用外部服务更新当前用户余额
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return true;
    }
    
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值