Spring-boot 中@Async使用遇到的坑

 更新时间:2024年01月19日 08:58:58   作者:hello|world  
这篇文章主要介绍了Spring-boot 中@Async使用的坑,首先使用@Async 需要在Spring启动类上添加注解@EnableAsyn或者在你们线程池配置类添加@EnableAsyn,需要的朋友可以参考下

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使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot实现插件化架构的4种方案详解

    SpringBoot实现插件化架构的4种方案详解

    在复杂业务场景下,传统的单体应用架构往往面临着功能扩展困难等困难,插件化架构作为一种模块化设计思想的延伸,能够使系统具备更好的扩展性和灵活性,下面我们来看看SpringBoot环境下实现插件化架构的4种实现方案吧
    2025-05-05
  • Java的Servlet及其生命周期详解

    Java的Servlet及其生命周期详解

    这篇文章主要介绍了Java的Servlet及其生命周期详解,Servlet是用Java编写的服务器端程序,一门用于开发动态web资源的技术,其主要功能在与交互式的浏览和修改数据,生成动态web内容,需要的朋友可以参考下
    2023-11-11
  • log4j2 项目日志组件的实例代码

    log4j2 项目日志组件的实例代码

    下面小编就为大家分享一篇log4j2 项目日志组件的实例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • 详谈Lock与synchronized 的区别

    详谈Lock与synchronized 的区别

    下面小编就为大家带来一篇详谈Lock与synchronized 的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • MyBatis的一级缓存和二级缓存以及优点说明

    MyBatis的一级缓存和二级缓存以及优点说明

    MyBatis的缓存机制包括一级缓存和二级缓存,一级缓存是SqlSession级别的缓存,开启默认,二级缓存是跨SqlSession的缓存,需要手动开启和配置,二级缓存的优点是减少数据库访问、提高性能、降低负载和提高可扩展性,同时需要注意缓存可能导致的数据不一致问题
    2025-02-02
  • SpringBoot中循环依赖的常见陷阱与解决方案

    SpringBoot中循环依赖的常见陷阱与解决方案

    循环依赖指两个或多个Bean相互依赖对方,形成一个闭环,本文将深入探讨循环依赖的根源,分析Spring的解决策略,并提供多种实战解决方案,希望对大家有所帮助
    2025-05-05
  • Spring cloud restTemplate 传递复杂参数的方式(多个对象)

    Spring cloud restTemplate 传递复杂参数的方式(多个对象)

    这篇文章主要介绍了Spring cloud restTemplate 传递复杂参数的方式(多个对象),需要的朋友可以参考下
    2018-05-05
  • 鸿蒙与Java跨平台Socket通信实战代码实例

    鸿蒙与Java跨平台Socket通信实战代码实例

    Socket是网络编程的基础,提供了进程间通信的通用接口,下面这篇文章主要介绍了鸿蒙与Java跨平台Socket通信实战的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-03-03
  • java实现Redisson的基本使用

    java实现Redisson的基本使用

    Redisson是一个在Redis的基础上实现的Java驻内存数据网格客户端,本文主要介绍了java实现Redisson的基本使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Java字符串替换函数replace()用法解析

    Java字符串替换函数replace()用法解析

    这篇文章主要介绍了Java字符串替换函数replace()用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01

最新评论