JJava 知识库
JAVA INTERVIEW

高频面试题

Java多线程进阶约 2 分钟

一个首页接口要并行调用商品、库存、营销和推荐服务,你会怎么用 CompletableFuture 编排?

参考回答约 2 分钟 · 口语表达
我的判断

首页聚合要并行的是相互独立的 I/O,核心做法是独立执行器、统一 deadline、局部降级和明确的结果组合。

商品、库存、营销和推荐之间没有依赖时可以并行,但我不会用默认 commonPool。这些都是阻塞 RPC,会放到专用有界线程池,并按下游分别限制并发。请求先算出总 deadline,各子调用拿剩余时间,不能每个都再等完整的两秒。

var product = supplyAsync(this::loadProduct, productPool);
var stock = supplyAsync(this::loadStock, stockPool);
var promo = supplyAsync(this::loadPromo, promoPool)
    .completeOnTimeout(Promo.empty(), 120, MILLISECONDS);

商品和库存失败可能直接失败,推荐和营销可以返回空结果。组合时用 thenCombine 表达依赖,不在异步任务内部反复 join 把线程重新阻塞。接口结束或超时后取消还没必要执行的任务,并把 trace 上下文传进去。

压测会比较串行与并行后的 P95/P99、线程池队列、下游并发和超时率。并行能降低等待总时长,也会瞬间放大四倍下游流量,所以必须和限流一起设计。