0

0

如何在Spring Boot中使用异步方法_@Async注解与自定义线程池实战

P粉602998670

P粉602998670

发布时间:2026-03-18 13:35:31

|

362人浏览过

|

来源于php中文网

原创

@Async不生效主因是同一类内调用、非public方法、非Spring管理Bean、未配置线程池等;需确保外部调用、public方法、Spring容器托管、指定ThreadPoolTaskExecutor并验证线程名。

如何在spring boot中使用异步方法_@async注解与自定义线程池实战

@Async 注解不生效的常见原因

直接在同一个类里调用 @Async 方法,几乎必然失效——Spring 的代理机制只对“外部 Bean 调用”起作用。这不是 bug,是 AOP 代理的天然限制。

  • 方法必须是 public 的,private/protected 方法加了注解也无效
  • 目标类必须由 Spring 容器管理(即不能 new 出来)
  • 调用方和被调用方不能是同一个 Bean 实例(否则绕过代理)
  • 如果用了 CGLIB 代理,需确保类不是 final 的,方法也不能是 final/static

典型错误现象:@Async 方法执行时主线程仍阻塞、日志没进异步线程、Thread.currentThread().getName() 还是 main 或 tomcat-xxx

自定义线程池为什么必须显式配置

Spring 默认用 SimpleAsyncTaskExecutor,它不复用线程,每次新建线程,高并发下容易 OOM。真要异步,必须配一个真正的线程池。

  • ThreadPoolTaskExecutor 是最常用选择,支持 core/max pool size、队列容量、拒绝策略
  • 别直接用 Executors.newFixedThreadPool() —— 它的无界队列 + 不可配置性,在 Spring 环境里属于反模式
  • 线程名建议设前缀(如 setThreadNamePrefix("async-task-")),方便排查日志归属
  • 拒绝策略推荐 CallerRunsPolicy,避免任务丢失,但要注意它会让调用线程自己执行,可能拖慢上游

示例配置片段:

@Bean("taskExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(4);
    executor.setMaxPoolSize(8);
    executor.setQueueCapacity(100);
    executor.setThreadNamePrefix("async-task-");
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
}

@Async 方法的返回值与异常处理陷阱

@Async 方法返回 voidFuture<?>,但两者行为差异很大,且异常默认不抛给调用方。

Buildt.ai
Buildt.ai

AI驱动的软件开发平台,可以自动生成代码片段、代码分析及其他自动化任务

下载
  • 返回 void:异常会被吞掉,仅记录在日志里(ERROR 级别),调用方完全感知不到失败
  • 返回 Future<T>:必须手动调用 future.get() 才会触发异常传播,否则照样静默
  • 若用 CompletableFuture,得配合 handle()exceptionally() 显式处理,不能依赖 try-catch 包裹异步调用
  • Spring 不会自动为 @Async 方法织入事务,即使方法上有 @Transactional,也大概率不在同一事务上下文

常见错误现象:异步方法里数据库更新失败,但主流程没报错、数据也没写进去、日志里只有一行 “java.lang.RuntimeException: xxx” 埋在角落

如何确认异步真正跑在指定线程池上

光看代码配了线程池不够,得验证实际执行线程是否来自你定义的 Bean。

  • @Async 方法开头打日志:log.info("Running on thread: {}", Thread.currentThread().getName());
  • 检查输出是否匹配你设置的 threadNamePrefix(比如 async-task-1
  • 别只测单次调用——多压几次,观察线程名是否轮转(如 async-task-1async-task-2),确认复用逻辑生效
  • 如果看到 ForkJoinPool.commonPool-worker-xmain,说明根本没走你的线程池,大概率是代理没生效或没指定 executor

指定线程池的方式有两种:全局默认(@EnableAsync(proxyTargetClass = true)taskExecutor Bean),或方法级(@Async("taskExecutor"))。后者优先级更高,但别混用,容易漏掉配置。

线程池大小不是越大越好,尤其涉及 DB 或远程调用时,盲目扩大会加剧连接竞争和上下文切换开销。真实场景里,先从 2–4 核心线程起步,再按监控(如 active count、queue size、reject count)逐步调优。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
如何配置Tomcat环境变量
如何配置Tomcat环境变量

配置Tomcat环境变量需要在系统中添加CATALINA_HOME变量,并将Tomcat的安装路径添加到PATH变量中。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

117

2023.10.26

idea如何集成Tomcat
idea如何集成Tomcat

idea集成Tomcat的步骤:1、添加Tomcat服务器配置;2、配置项目部署;3、运行Tomcat服务器;4、访问项目;5、注意事项;6、关闭Tomcat服务器。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

173

2024.02.23

怎么查看Tomcat源代码
怎么查看Tomcat源代码

查看Tomcat源代码的步骤:1、下载Tomcat源代码;2、在IDEA中导入Tomcat源代码;3、查看源代码;4、理解Tomcat的工作原理;5、参与社区和贡献;6、注意事项;7、持续学习和更新;8、使用工具和插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

99

2024.02.23

常见的tomcat漏洞有哪些
常见的tomcat漏洞有哪些

常见的tomcat漏洞有:1、跨站脚本攻击;2、跨站请求伪造;3、目录遍历漏洞;4、缓冲区溢出漏洞;5、配置漏洞;6、第三方组件漏洞。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

170

2024.02.23

tomcat日志乱码怎么解决
tomcat日志乱码怎么解决

tomcat日志乱码的解决办法:1、修改tomcat的日志编码设置;2、检查ide的编码设置;3、检查操作系统的编码设置;4、使用过滤器处理日志;5、检查外部系统的编码设置;6、检查文件编码方式等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

159

2024.02.23

weblogic和tomcat有哪些区别
weblogic和tomcat有哪些区别

weblogic和tomcat的区别:1、功能;2、性能;3、规模;4、价格;5、安全性;6、配置和管理;7、社区支持;8、集成能力;9、升级和更新;10、可靠性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

200

2024.02.23

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

245

2024.02.23

tomcat启动闪退怎么解决
tomcat启动闪退怎么解决

tomcat启动闪退的解决办法:1、检查java环境;2、检查环境变量配置;3、检查端口被占用;4、检查配置文件编码;5、检查启动时需要的配置文件;6、检查相关文件是否丢失;7、检查防火墙和杀毒软件设置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

170

2024.02.23

Python WebSocket实时通信与异步服务开发实践
Python WebSocket实时通信与异步服务开发实践

本专题聚焦 Python 在实时通信场景中的开发实践,系统讲解 WebSocket 协议原理、长连接管理、消息推送机制以及异步服务架构设计。内容包括客户端与服务端通信实现、连接稳定性优化、消息队列集成及高并发处理策略。通过完整案例,帮助开发者构建高效稳定的实时通信系统,适用于聊天应用、实时数据推送等场景。

3

2026.03.18

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号