1. Async的作用一、核心作用Async是 Spring 提供的异步执行注解作用把被标注的方法放到独立线程异步执行不会阻塞当前调用主线程实现任务解耦、提升接口响应速度常用于异步通知、日志、文件导出、消息发送等耗时操作。二、使用前提必须两步缺一不可启动类添加EnableAsync开启异步功能javaSpringBootApplication EnableAsync // 开启Spring异步支持 public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }Async写在public 方法上且调用方和异步方法不在同一个类内部调用不生效AOP 无法拦截三、两种返回形式1. 无返回值void适合不需要接收结果的耗时任务发短信、记录操作日志javaAsync public void sendSms(String phone) { // 耗时网络操作异步执行不阻塞主线程 }2. 有返回值返回 FutureT / CompletableFutureT需要获取异步执行结果、做结果聚合javaAsync public FutureInteger countOrder() { int total orderMapper.selectCount(null); return CompletableFuture.completedFuture(total); } // 调用 FutureInteger future orderService.countOrder(); Integer total future.get(); // 阻塞等待异步结果四、底层原理Spring 通过AOP 动态代理拦截Async方法拦截到方法后把任务交给内置线程池SimpleAsyncTaskExecutor新开子线程执行目标方法主线程直接返回不等待方法执行完毕。五、默认线程池问题重要默认使用SimpleAsyncTaskExecutor每次调用新建一个线程无复用、无限创建线程高并发会 OOM。生产环境自定义线程池方案javaConfiguration public class AsyncConfig { Bean(taskExecutor) public Executor taskExecutor() { ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); // 核心线程 executor.setMaxPoolSize(50); // 最大线程 executor.setQueueCapacity(200); // 队列 executor.setThreadNamePrefix(async-task-); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } } // 指定使用自定义线程池 Async(taskExecutor) public void asyncTask(){}六、常见坑同类内部调用失效java// 同一个类里调用AOP代理拦截不到同步执行 public void test(){ asyncMethod(); // 无效同步 } Async public void asyncMethod(){}解决把异步方法抽离到单独 Service或者通过ApplicationContext获取代理对象调用。事务失效异步方法会新开线程子线程和主线程是独立事务主线程回滚不影响异步方法。异常捕获void 异步方法抛出异常主线程感知不到需要自定义AsyncUncaughtExceptionHandler统一捕获异常告警。事务传播问题主线程事务不会传递到异步子线程各自独立。七、适用场景 不适用场景适用异步通知短信、邮件、站内信后置统计操作日志、埋点数据上报耗时计算报表生成、大数据导出MQ 消息异步发送不适用需要同步事务保证一致性的核心业务订单创建 库存扣减不能分开异步需要实时拿到返回结果且不能阻塞的简单接口同步即可八、和手动创建线程的区别Async托管线程池统一管控、可配置拒绝策略统一异常处理、线程复用不用手动管理 Thread支持返回 Future 异步结果获取代码更简洁。