主题切换
异步调用
一、业务场景说明
场景示例:搜索记录异步保存
用户在前端执行搜索操作,主流程仅负责返回搜索结果页面;用户搜索记录入库操作不阻塞主业务,交给线程池异步执行。
- 主线程逻辑:接收搜索关键词 → 查询搜索数据 → 直接返回页面给用户;
- 异步任务逻辑:在线程池分配独立线程,执行搜索记录入库、热点统计等后置操作。
核心价值
无需等待后置IO操作完成,直接返回响应,缩短接口RT,提升用户访问速度。
二、适用条件
- 后置任务不需要返回结果,主流程不依赖该任务执行完毕;
- 后置任务为非核心链路:操作日志、搜索记录、短信/站内信发送、统计埋点、缓存更新等。
三、代码示例
java
// 自定义业务线程池
ThreadPoolExecutor pool = new ThreadPoolExecutor(8, 16, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(200), new ThreadPoolExecutor.CallerRunsPolicy());
@GetMapping("/search")
public Result<List<ArticleVO>> search(String keyword) {
// 1. 主线程执行核心查询,立刻返回结果
List<ArticleVO> result = articleService.search(keyword);
// 2. 异步提交日志保存任务,不阻塞主线程
pool.execute(() -> {
SearchRecord record = new SearchRecord();
record.setKeyword(keyword);
record.setCreateTime(new Date());
searchRecordMapper.insert(record);
// 额外热点统计、埋点上报
});
return Result.success(result);
}使用pool.execute(Runnable),无返回值,纯异步后置处理。
四、项目三大多线程场景完整总结
批量导入(线程池 + CountDownLatch) 千万级DB数据同步ES,分页分片并发写入,CountDownLatch控制主线程等待全部导入任务完成,一次性加载数据避免OOM。
数据汇总(线程池 + Future) 多个无依赖微服务/报表接口并行查询,Future接收各任务返回值,将串行耗时压缩为最慢接口耗时,优化接口响应速度。
异步调用(线程池 execute) 无返回值的后置操作(日志、记录、消息推送)异步执行,解除主流程IO阻塞,提升接口吞吐量。
五、面试标准回答
问:项目中哪里用到异步多线程? 答: 用户搜索功能中,查询文章列表是核心流程,搜索记录入库属于后置非核心逻辑。我把保存记录的逻辑提交到自定义线程池异步执行,主线程不用等待数据库写入,直接返回搜索结果,减少接口响应耗时。 除此之外还有两类场景:大批量数据同步ES使用CountDownLatch等待全部分片任务完成;订单详情多微服务数据聚合使用Future并行查询,优化串行调用耗时。