spring的异步实现:@Async
1 通过注解@Async实现异步处理
在项目的启动类中加入注解@EnableAsync
在需要实现异步的方法上面加上注解@Async
以外露接口的形式,在controller层调用,就可以实现异步效果,代码如下
controller层代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @RestController public class AsyncController { private static final Logger logger = LoggerFactory.getLogger(AsyncController. class ); @Autowired private IAsyncService asyncService; /** * 测试spring的异步调用顺序 * * @return */ @GetMapping ( "/async" ) public String asyncTest() { logger.info( "************ 执行第一步 ************" ); asyncService.sync(); asyncService.springAsync(); logger.info( "************ 执行第二步 ************" ); return "success" ; } } |
service层代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | @Service public class AsyncServiceImpl implements IAsyncService { private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl. class ); /** * spring的异步调用 */ @Async @Override public void springAsync() { logger.info( "************ 执行异步start ************" ); try { Thread.sleep( 3000 ); } catch (InterruptedException e) { e.printStackTrace(); } logger.info( "************ 执行异步end ************" ); } /** * 同步方法 * * @return 执行结果 */ @Override public String sync() { logger.info( "************ 执同步方法 start ************" ); logger.info( "************ 执同步方法 end ************" ); return "success" ; } |
执行结果:从结果来看,程序先执行完controller层的代码,返回结果,然后才进行带有@Async的代码。实现了我们预期的效果
1 2 3 4 5 6 | 21 : 25 : 35.824 [http-nio- 8815 -exec- 1 ] INFO c.s.c.c.AsyncController - [asyncTest, 28 ] - ************ 执行第一步 ************ 21 : 25 : 35.824 [http-nio- 8815 -exec- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [sync, 39 ] - ************ 执同步方法 start ************ 21 : 25 : 35.824 [http-nio- 8815 -exec- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [sync, 40 ] - ************ 执同步方法 end ************ 21 : 25 : 35.827 [http-nio- 8815 -exec- 1 ] INFO c.s.c.c.AsyncController - [asyncTest, 31 ] - ************ 执行第二步 ************ 21 : 25 : 35.827 [task- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [springAsync, 23 ] - ************ 执行异步start ************ 21 : 25 : 38.829 [task- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [springAsync, 29 ] - ************ 执行异步end ************ |
2 直接在service层的同一个java文件中调用带有@Async注解的方法,不能实现异步效果。
controller层代码:
@RestController public class AsyncController { private static final Logger logger = LoggerFactory.getLogger(AsyncController.class); @Autowired private IAsyncService asyncService; /** * 测试spring的异步调用顺序 * * @return */ @GetMapping("/async") public String asyncTest() { logger.info("************ 执行第一步 ************"); asyncService.sync(); logger.info("************ 执行第二步 ************"); return "success"; } }
service层代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | @Service public class AsyncServiceImpl implements IAsyncService { private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl. class ); /** * spring的异步调用 */ @Async @Override public void springAsync() { logger.info( "************ 执行异步start ************" ); try { Thread.sleep( 3000 ); } catch (InterruptedException e) { e.printStackTrace(); } logger.info( "************ 执行异步end ************" ); } /** * 同步方法 * * @return 执行结果 */ @Override public String sync() { logger.info( "************ 执同步方法 start ************" ); springAsync(); logger.info( "************ 执同步方法 end ************" ); return "success" ; } } |
执行结果:从结果来看,异步方法执行结束后才结束了一次请求,失去了异步的效果
1 2 3 4 5 6 | 21 : 05 : 15.397 [http-nio- 8815 -exec- 1 ] INFO c.s.c.c.AsyncController - [asyncTest, 28 ] - ************ 执行第一步 ************ 21 : 05 : 15.463 [http-nio- 8815 -exec- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [sync, 39 ] - ************ 执同步方法 start ************ 21 : 05 : 15.463 [http-nio- 8815 -exec- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [springAsync, 23 ] - ************ 执行异步start ************ 21 : 05 : 18.464 [http-nio- 8815 -exec- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [springAsync, 29 ] - ************ 执行异步end ************ 21 : 05 : 18.464 [http-nio- 8815 -exec- 1 ] INFO c.s.c.s.i.AsyncServiceImpl - [sync, 41 ] - ************ 执同步方法 end ************ 21 : 05 : 18.464 [http-nio- 8815 -exec- 1 ] INFO c.s.c.c.AsyncController - [asyncTest, 30 ] - ************ 执行第二步 ************ |
* 补充:何为同步异步?
同步:就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。
异步:则只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。(在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。)
总结:同spring的事务类似。spring的事务是通过代理实现的,如果需要让事务生效,那么必须要走代理才可以。除了上述的方案之外,还可以进行将AsyncServiceImpl 自己注入自己,这样就也可以生效。
本文来自博客园,作者:zhangpba,转载请注明原文链接:https://www.cnblogs.com/zhangpb/p/14463942.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具