当前位置:首页 > 技术分析 > 正文内容

正确使用@Async,避免踩坑_@async注意事项

ruisui883个月前 (02-14)技术分析10

用法和介绍

功能描述

@Async是Spring提供的使方法异步的注解

使用方法

  1. SpringBoot项目启动类增加@EnableAsync注解,开启异步功能
  2. 给需要异步的方法增加@Async("")注解,一定要指定线程池名称

代码示例

@EnableAsync
@SpringBootApplication
public class StartApplication {
    public static void main(String[] args) {
        SpringApplication.run(StartApplication.class, args);
    }
}
@Service
public class AsyncService {
    /**
     * 使用默认线程池
     */
    @Async
    public void say(){ }
    
    /**
     * 指定线程池名称
     */
    @Async("getAsyncExecutor")
    public void eat(){ }
}
@Configuration
public class MyAsyncConfiguration {
    //核心线程数
	  private static final int CORE_POOL_SIZE = 5;
	  //最大线程数
	  private static final int MAX_POOL_SIZE = 15;
	  //队列大小
	  private static final int QUEUE_CAPACITY = 100;
	  //线程池中的线程的名称前缀
	  private static final String THREAD_NAME = "MyThread-";

	  @Bean
	  public Executor getAsyncExecutor() {
		    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		    //配置核心线程数
		    executor.setCorePoolSize(CORE_POOL_SIZE);
		    //配置最大线程数
		    executor.setMaxPoolSize(MAX_POOL_SIZE);
		    //配置队列大小
		    executor.setQueueCapacity(QUEUE_CAPACITY);
		    //配置线程池中的线程的名称前缀
		    executor.setThreadNamePrefix(THREAD_NAME);
		    //配置线程池拒绝策略,设置为CallerRunsPolicy,当线程和队列都满了,由发起线程的主线程自己执行
		    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		    executor.initialize();
		    return executor;
	  }
}

已实现的TaskExecutor线程池

  • SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程。
  • SyncTaskExecutor:这个类没有实现异步调用,只是一个同步操作,只适用于不需要多线程的地方。
  • ConcurrentTaskExecutor:Executor的适配类,不推荐使用。如果ThreadPoolTaskExecutor不满足要求时,才用考虑使用这个类 。
  • SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的类。线程池同时被quartz和非quartz使用,才需要使用此类。
  • ThreadPoolTaskExecutor :最常使用,推荐。 其实质是对java.util.concurrent.ThreadPoolExecutor的包装。


为什么说一定要指定线程池名称

@Async依赖线程池,当我们未指定线程池@Async会如何选择呢?

1. 当系统未配置任何线程池时

SpringBoot会默认添加一个coreSize=8的 ThreadPoolTaskExecutor 无界线程池,名称applicationTaskExecutor。

2. 当只配置了一个TaskExecutor线程池时

使用此线程池

3. 当只配置了一个线程池,但不是TaskExecutor线程池时

使用 SimpleAsyncTaskExecutor 线和池

4. 当有多个TaskExecutor线程池时

默认使用 SimpleAsyncTaskExecutor 线程池,如果指定就使用指定的线程池(即使不是TaskExecutor类型的线程池也可以)

注意:SimpleAsyncTaskExecutor 不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程。强烈建议开发时指定线程池的名称,避免创建多个TaskExecutor实例后,使用 SimpleAsyncTaskExecutor 线和池的情况发生

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/1939.html

标签: aysnc
分享给朋友:

“正确使用@Async,避免踩坑_@async注意事项” 的相关文章

Ubuntu Linux 24.04 LTS发行版现已开放下载

IT之家 4 月 25 日消息,Ubuntu 24.04 长期支持版(LTS)“Noble Numbat” 现已发布,有需要的用户请通过官网下载发行版 ISO 镜像进行安装。Ubuntu 24.04 采用了 Linux 6.8 内核,可利用 Netplan 在桌面上配置网络连接,还配备了现代化的桌面...

2021最全VUE面试题,奥利给

1. vue-router用过没,哪些常用的钩子函数路由钩子的执行流程,钩子函数种类有:全局守卫、路由守卫、组件守卫。首页可以控制导航跳转, beforeEach , afterEach 等,?般?于页? title 的修改。?些需要登录才能调整??的重定向功能。beforeEach 主要有3个参数...

10分钟搞定gitlab-ci自动化部署

gitlab-ci 是持续集成工具/自动化部署工具,类似 jenkins。持续集成 是将代码集成到共享存储库并尽可能早地自动构建/测试每个更改的实践 - 通常一天几次。概述在编码完成时都会进行打包发布过程,如果每次都手动操作这一步骤就会浪费时间,效率低下。所以就有了持续集成。准备事项请提前安装以下软...

美国民众负债累累 但今年假期消费者支出仍将创下新高

智通财经APP获悉,在迎接假期之际,许多美国人已经背负了创纪录的信用卡债务。然而,今年假期消费者支出仍将创下新高。根据美国零售联合会(NRF)上周发布的报告,预计今年11月1日至12月31日期间的消费总额将达到创纪录的9795亿至9890亿美元之间。NRF首席经济学家Jack Kleinhenz表示...

VUE-router

七.Vue-router1、什么是vue-routervue-router是vue.js官方路由管理器。vue的单页应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统页面切换是用超链接a标签进行切换。但vue里是用路由,因为我们用Vue做的都是单页应用,就相当于只有一个主的i...

关于Vue页面跳转传参,参数不同, 但页面只获取参数一次的问题

#头条创作挑战赛#1.问题描述问题描述: element 展示表格(页面A),点击表格的每一行的查看详情按钮,可以携带此行的信息参数跳转到另一个页面(页面B),但是从A页面到B页面,只有第一次跳转的时候B页面可以获取到A页面的参数,返回再次A->B ,B页面无法获取到参数。2.解决办法:方法一...