@EnableAsync @Async
一. 基本介绍
@Async是spring为了方便开发人员进行异步调用的出现的,在方法上加入这个注解,spring会从线程池中获取一个新的线程来执行方法,实现异步调用
@EnableAsync表示开启对异步任务的支持,可以放在springboot的启动类上,也可以放在自定义线程池的配置类上,具体看下文
二.最简单的使用
在springboot项目中,直接在启动类上加上@EnableAsync,然后在service层的方法上对于需要异步调用的方法加上@Async,
那么当controller层调用这个方法的时候,就会在主线程外自动新建线程执行该方法,具体看下图demo
1.springboot启动类开启异步支持
2.service层的方法加@Async,如果在类上加该注解表示整个类的方法都异步执行,建议加到具体的某个方法上
3.controller层调用service层的异步方法,这里用主线程在异步方法前后执行了2次打印输出
4.调用的结果
首先看看没有异步执行,正常的顺序执行的结果
可以看到,按顺序执行,全部是main线程http-nio-8181-exec-124执行,并且service方法的执行结果在中间,如下所示
由于我们的方法使用了@Async注解,所以主线程http-nio-8181-exec-124不等异步方法完成,先结束了,异步线程task-1继续执行
tips:没有自定义线程池@Async默认的线程池是SimpleAsyncTaskExecutor
三.自定义线程池来使用@Async
1.新建一个线程池配置类,@EnableAsync在配置类上加,不用在启动类上加也行,可以配置不同的线程池,用bean的name做区分
2.@Async的使用一样是在service层的方法上加,如果配置了多个线程池,可以用@Async("name"),那么表示线程池的@Bean的name,来指定用哪个线程池处理
假如只配置了一个线程池,直接用@Async就会用自定义的线程池执行
假如配置了多个线程池,用@Async没指定用哪个线程池,会用默认的SimpleAsyncTaskExecutor来处理
假如配置了多个线程池,用@Async("name"),会用指定的线程池处理
比如service层方法上指定pool1线程池
执行结果,异步线程名是pool配置的fzhThread
https://www.cnblogs.com/fzhblog/p/14012401.html
四.注解没生效的原因
1.异步方法使用static修饰
2.异步方法类没有使用@Service注解(或其他注解)导致spring无法扫描到异步类
3.controller中需要使用@Autowired或@Resource等注解自动注入service类,不能自己手动new对象
我们在使用多线程的时候,往往需要创建Thread类,或者实现Runnable接口,来创建Executors,在使用spring中,已经给我们做了很好的支持,只要使用@Async可以定义一个线程任务。通过spring给我们提供的ThreadPoolTaskExecutor就可以使用线程池。
默认情况下,Spring将搜索相关的线程池定义:要么在上下文中搜索唯一的TaskExecutor bean,要么搜索名为“taskExecutor”的Executor bean。如果两者都无法解析,则将使用SimpleAsyncTaskExecutor来处理异步方法调用。
标签:
相关文章
-
无相关信息