使用@async注解实现异步调用

Posted1 by 呼延十 on October 29, 2018 Hot:

什么是异步调用?

异步调用对应的是同步调用,假设现在有三个无关任务等待执行,同步调用的方式是逐次等待,即第一个任务完成后再开始第二个任务….以此类推。

但是计算机可以并发执行,使用同步调用的耗时太长了,因此我们希望开三个县城去同时的处理这三个任务,这就需要使用@Async注解了。

如何使用@Async

在spring boot项目中使用@Async注解十分的方便。

只需要在项目启动类上添加@EnableAsync注解,之后在想要异步调用的方法上添加@Async 即可。

使用实例

首先我们来看一下同步调用的结果。

在我们的测试类中添加以下三个方法。

然后调用它。

执行结果如下图所示:

可以看到,三个任务是依次执行的,并且使用同一个线程调用。

总的耗时等于三个任务耗时之和。

那么异步调用呢? 首先添加一个TestService类,在该类中添加上述三个方法并且各自打上@Async注解。 如下图所示:

调用它。

得到的结果如下所示:

可以清楚的看到,首先打印的是完成所有任务,因为只是主线程只是负责启动这三个任务,之后便输出了打印语句,而没有等到任务完成。

同时,可以清晰的看到,三个任务随机开始随机结束,且在不同的线程中运行。

@Async注解的使用非常的简单,但是却很实用,编码过程中有许多不需要等待结果的调用(当然需要结果我们也可以通过Future拿到),这时可以使用此注解,提高总结果返回的速度。

注意事项

我在初次使用@Async时曾经踩过一个坑,我只注意到大佬们使用此注解却没有详细看,将异步方法和调用他的方法写在了同一个类里,导致异步注解没有起到效果。这里说明一下为什么。

图片转自参考链接:

当我们给A类的b方法打上了@Async注解(图中为@Transactinal,原理同样),spring扫描到注解后,为A类创建了一个代理类proxy$A,并且给有注解的方法开始的部分添加了对应的操作,图中为startTransaction(),使用@Async时为新启动一个线程的操作(没有具体看源码)。

此时如果通过A类的实例调用a方法,在标记3的地方,之后跳转至标记1,之后调用原先的b方法,没有启动新的线程。

而通过B类的实例直接调用A类的b方法,则在标记2处,此处由spring自动添加了启动新线程的操作,因此可以实现异步调用。

后记

并发编程是程序员绕不过去的坎,否则你的服务天天超时,监控工具都会看不下去的,而@Async是很基础的并发知识,甚至不算知识,知识简单的调用,却能为我们的程序运行速度带来很大的提升。

参考链接

https://blog.csdn.net/qq_34581118/article/details/78262900


完。





ChangeLog

2018-10-29 完成

以上皆为个人所思所得,如有错误欢迎评论区指正。

欢迎转载,烦请署名并保留原文链接。

联系邮箱:huyanshi2580@gmail.com

更多学习笔记见个人博客——>呼延十