主题切换
数据汇总
一、业务场景:电商多微服务数据汇总
1. 串行执行痛点
订单详情需要同时拉取3个无依赖微服务数据:
- 订单基础信息:500ms
- 商品明细信息:800ms
- 物流配送信息:500ms 串行调用总耗时 = 500 + 800 + 500 = 1800ms,接口响应缓慢,用户体验差。
2. 线程池+Future并行优化
将3个查询任务提交线程池并发执行,三者互不阻塞,整体耗时等于最慢接口耗时 800ms,大幅缩短接口RT。 适用场景:多无依赖接口聚合、后台报表多维度数据统计。
二、Future 完整讲解
1. 核心作用
Future 是线程池异步任务的返回句柄,配合 threadPool.submit(Callable) 使用,用来获取异步线程的执行结果。
- Runnable无返回值,submit后返回Future,get()会阻塞等待任务结束;
- Callable带返回值,Future.get()可以拿到任务计算结果。
2. 核心API
V get()阻塞方法,一直等待直到异步任务执行完成,返回任务结果;任务抛异常时,get()会捕获抛出ExecutionException。V get(long timeout, TimeUnit unit)带超时阻塞,超过指定时间任务未完成直接抛出超时异常,避免无限阻塞。boolean isDone()判断任务是否执行完毕(正常完成/异常终止/手动取消都返回true)。boolean cancel(boolean mayInterruptIfRunning)尝试取消正在执行的任务;参数true代表中断运行中的线程,false仅取消未开始的任务。boolean isCancelled()任务完成前是否被取消。
3. 代码示例(电商数据汇总)
java
// 自定义业务线程池
ThreadPoolExecutor pool = new ThreadPoolExecutor(4, 8, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(200), new ThreadPoolExecutor.CallerRunsPolicy());
// 提交3个并行查询任务
Future<OrderDTO> orderFuture = pool.submit(() -> orderFeign.getOrderInfo(orderId));
Future<List<GoodsDTO>> goodsFuture = pool.submit(() -> goodsFeign.getGoodsList(orderId));
Future<LogisticsDTO> logisticsFuture = pool.submit(() -> logisticsFeign.getLogistics(orderId));
// 阻塞获取所有结果,完成数据汇总
OrderDTO order = orderFuture.get();
List<GoodsDTO> goodsList = goodsFuture.get();
LogisticsDTO logistics = logisticsFuture.get();
// 组装返回VO
OrderDetailVO vo = assembleData(order, goodsList, logistics);三、使用优缺点
优点
- 并行执行无依赖任务,大幅降低接口响应时间;
- 支持超时控制,防止异步任务卡死拖垮主线程;
- 可主动取消任务、判断任务执行状态,管控能力强。
缺点
get()阻塞主线程,批量获取多个Future时依旧会串行等待最慢任务;- 无法回调,必须主动调用get才能拿到结果;
- 大量Future手动管理繁琐,JDK8后推荐使用
CompletableFuture实现异步回调。
四、同类拓展场景
- 后台运营报表:同时查询支付、访客、订单、点赞多维度统计数据,并行汇总;
- 首页多模块渲染:商品、优惠券、活动、用户信息分线程并行拉取;
- 多第三方接口并行调用:物流、支付、短信渠道同步查询。
五、面试简答
问:Future在项目中怎么用?解决什么问题? 答: 在电商订单详情接口、后台报表汇总场景使用,多个互不依赖的微服务查询任务通过线程池submit提交,返回Future对象。调用get()阻塞获取各接口返回数据,将串行查询改为并行执行,把接口总耗时从多接口累加缩短至最慢单个接口耗时,优化响应速度。 Future核心作用是接收Callable异步任务返回值,支持超时等待、任务取消、状态判断;缺点是阻塞获取结果,复杂异步场景会用CompletableFuture替代。