MST

星途 面试题库

面试题:Java CompletableFuture在复杂业务场景下的链式与组合优化

在一个电商系统中,需要从商品库存服务获取商品库存数量,然后根据库存数量判断是否有促销活动(如果库存大于100则有促销活动),如果有促销活动,再从促销服务获取促销信息并返回给前端展示。请使用CompletableFuture的链式调用与组合,结合线程池优化,以最高效的方式实现这个业务逻辑。要求代码具有良好的扩展性和可读性,同时考虑到各服务调用可能出现的超时、异常等情况并进行处理。请详细说明设计思路并编写Java代码。
43.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 线程池:创建一个线程池来执行异步任务,避免为每个任务创建新线程带来的开销。
  2. CompletableFuture链式调用:使用CompletableFuture的链式调用,使得代码逻辑清晰,易于理解和维护。
  3. 异常处理:通过exceptionally方法处理每个异步任务可能抛出的异常,保证系统的健壮性。
  4. 超时处理:使用orTimeout方法设置每个异步任务的超时时间,防止长时间等待。

Java代码

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class EcommerceSystem {
    // 创建线程池
    private static final ExecutorService executorService = Executors.newFixedThreadPool(10);

    // 模拟商品库存服务
    public static CompletableFuture<Integer> getProductStock() {
        return CompletableFuture.supplyAsync(() -> {
            // 模拟服务调用,这里返回一个随机数作为库存数量
            AtomicInteger stock = new AtomicInteger();
            stock.set((int) (Math.random() * 200));
            System.out.println("商品库存数量: " + stock.get());
            return stock.get();
        }, executorService);
    }

    // 模拟促销服务
    public static CompletableFuture<String> getPromotionInfo() {
        return CompletableFuture.supplyAsync(() -> {
            // 模拟服务调用,返回促销信息
            return "满减促销,满100减20";
        }, executorService);
    }

    public static CompletableFuture<String> checkPromotionAndGetInfo() {
        return getProductStock()
               .orTimeout(5, TimeUnit.SECONDS)
               .thenApplyAsync(stock -> {
                    if (stock > 100) {
                        return true;
                    }
                    return false;
                }, executorService)
               .thenComposeAsync(hasPromotion -> {
                    if (hasPromotion) {
                        return getPromotionInfo().orTimeout(5, TimeUnit.SECONDS);
                    }
                    return CompletableFuture.completedFuture("无促销活动");
                }, executorService)
               .exceptionally(ex -> {
                    System.out.println("发生异常: " + ex.getMessage());
                    return "服务异常,无法获取促销信息";
                });
    }

    public static void main(String[] args) {
        checkPromotionAndGetInfo().thenAccept(System.out::println).join();
        executorService.shutdown();
    }
}

代码说明

  1. 线程池创建ExecutorService executorService = Executors.newFixedThreadPool(10); 创建了一个固定大小为10的线程池。
  2. getProductStock方法:使用CompletableFuture.supplyAsync异步调用商品库存服务,并设置超时时间为5秒。
  3. getPromotionInfo方法:使用CompletableFuture.supplyAsync异步调用促销服务,并设置超时时间为5秒。
  4. checkPromotionAndGetInfo方法:通过链式调用实现业务逻辑,首先获取商品库存数量,判断是否有促销活动,有则获取促销信息,处理异常情况。
  5. main方法:调用checkPromotionAndGetInfo方法,并在最后关闭线程池。