首页 > 编程开发 > Java    日期:2024-01-24 / 来自博客园 / 浏览

很多人会直接只用@Async来执行异步操作。但是这里面有一个问题,如果都是用spring的默认实现,是有坑的。

当我们开启 EnableAsync注解 就可以使用@Async注解来执行异步操作了。

我们现在通过EnableAsync注解去打开spring异步世界的坑。

Spring的@Async使用防坑

走JDK的动态代理:

Spring的@Async使用防坑

Spring的@Async使用防坑

Spring的@Async使用防坑

 最终走到这儿来了:AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory)

Spring的@Async使用防坑

问题就在这里,如果我们自己没有定义 Executor,也就是上面从容器beanFactory 中拿不到Executor 那么就会使用--SimpleAsyncTaskExecutor,这玩意儿实际上根本不是线程池!!!!!

请看它的 doExecute 方法,直接new新的线程。

Spring的@Async使用防坑

所以这玩意儿一直都是在创建新的 线程执行任务。。。。。

修改方式:

方案1.@Async 指定我们自己的线程池执行:@Async("自己线程池beanName") 

方案2:回到AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory) 方法,看它如何获取线程池的:

Spring的@Async使用防坑

 要么我们自己配置一个TaskExecutor, 要么我们把我自己配置的线程池的名字叫做  taskExecutor 。这个常量的值:

DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor",这样可以避免使用SimpleAsyncTaskExecutor。

方案3:实现 AsyncConfigurer 接口作为一个配置类交给spring管理,通过 getAsyncExecutor 方法配置异步线程池。

Spring的@Async使用防坑

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章