Spring-boot 中@Async使用遇到的坑
作者:hello|world
Spring的@Async使用防坑
很多人会直接只用@Async来执行异步操作。但是这里面有一个问题,如果都是用spring的默认实现,是有坑的。
当我们开启EnableAsync注解 就可以使用@Async注解来执行异步操作了。
我们现在通过EnableAsync注解去打开spring异步世界的坑。
走JDK的动态代理:
最终走到这儿来了:AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory)
问题就在这里,如果我们自己没有定义Executor,也就是上面从容器beanFactory 中拿不到Executor 那么就会使用--SimpleAsyncTaskExecutor,这玩意儿实际上根本不是线程池!!!!!
请看它的doExecute 方法,直接new新的线程。
所以这玩意儿一直都是在创建新的 线程执行任务。。。。。
修改方式:
方案1.@Async 指定我们自己的线程池执行:@Async("自己线程池beanName")
方案2:回到AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory) 方法,看它如何获取线程池的:
要么我们自己配置一个TaskExecutor, 要么我们把我自己配置的线程池的名字叫做 taskExecutor 。这个常量的值:
DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor",这样可以避免使用SimpleAsyncTaskExecutor。
方案3:实现AsyncConfigurer 接口作为一个配置类交给spring管理,通过getAsyncExecutor 方法配置异步线程池。
Spring-boot 中@Async使用的坑
1、首先使用@Async 需要在Spring启动类上添加注解@EnableAsyn或者在你们线程池配置类添加@EnableAsyn
一下两种选择一种即可
@SpringBootApplication @EnableAsync public class SpringBootApplicationStart { public static void main(String[] args) { SpringApplication.run(SpringBootApplicationStart.class); } }
@EnableAsync @Configuration public class ThreadPoolConfig { @Bean("simpleThreadPool") public ThreadPoolTaskExecutor simpleThreadPool(){ ThreadPoolTaskExecutor simpleThreadPool = new ThreadPoolTaskExecutor(); simpleThreadPool.setCorePoolSize(5); simpleThreadPool.setMaxPoolSize(10); simpleThreadPool.setQueueCapacity(25); simpleThreadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); simpleThreadPool.initialize(); return simpleThreadPool; } }
注意如果自己配置了线程池那么在使用的时候需要保持一致
例如:@Async("simpleThreadPool")
2、在使用@Async的时候切记不要在一个类里面调用@Async声明的方法,会产生代理绕过问题。
@Async public void asyncProcess() throws InterruptedException { Thread.sleep(2000); }
3、注意写法
@Autowired private AsyncTaskService asyncTaskService; public String asyncMethod(String name,int age) { OnelogStats.trace("msg_async", "进入service"); try { // 初学者可能会有这种错误,AsyncTaskService没有注入到Spring导致Async不起作用,注释不规范 //new AsyncTaskService().asyncProcess(); asyncTaskService.asyncProcess(); } catch (InterruptedException e) { return "async error"; } return "I am " + name + ", I am " + age + " years old."; }
到此这篇关于Spring的@Async使用操遇到的坑的文章就介绍到这了,更多相关Spring @Async使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!