Skip to content

异步调用

一、业务场景说明

场景示例:搜索记录异步保存

用户在前端执行搜索操作,主流程仅负责返回搜索结果页面;用户搜索记录入库操作不阻塞主业务,交给线程池异步执行。

  1. 主线程逻辑:接收搜索关键词 → 查询搜索数据 → 直接返回页面给用户;
  2. 异步任务逻辑:在线程池分配独立线程,执行搜索记录入库、热点统计等后置操作。

核心价值

无需等待后置IO操作完成,直接返回响应,缩短接口RT,提升用户访问速度。

二、适用条件

  1. 后置任务不需要返回结果,主流程不依赖该任务执行完毕;
  2. 后置任务为非核心链路:操作日志、搜索记录、短信/站内信发送、统计埋点、缓存更新等。

三、代码示例

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),无返回值,纯异步后置处理。

四、项目三大多线程场景完整总结

  1. 批量导入(线程池 + CountDownLatch) 千万级DB数据同步ES,分页分片并发写入,CountDownLatch控制主线程等待全部导入任务完成,一次性加载数据避免OOM。

  2. 数据汇总(线程池 + Future) 多个无依赖微服务/报表接口并行查询,Future接收各任务返回值,将串行耗时压缩为最慢接口耗时,优化接口响应速度。

  3. 异步调用(线程池 execute) 无返回值的后置操作(日志、记录、消息推送)异步执行,解除主流程IO阻塞,提升接口吞吐量。

五、面试标准回答

问:项目中哪里用到异步多线程? 答: 用户搜索功能中,查询文章列表是核心流程,搜索记录入库属于后置非核心逻辑。我把保存记录的逻辑提交到自定义线程池异步执行,主线程不用等待数据库写入,直接返回搜索结果,减少接口响应耗时。 除此之外还有两类场景:大批量数据同步ES使用CountDownLatch等待全部分片任务完成;订单详情多微服务数据聚合使用Future并行查询,优化串行调用耗时。

Powered by VitePress 1.6.4 | 持续更新中