springboot之@Async异步定时任务自定义线程池

news2024/12/24 21:38:33
在应用中经常会遇到定时执行任务的需求,这时采用异步的方式开启一个定时任务,通常引用@Async注解,但直接使用会有风险,当我们没有指定线程池时,会默认使用其Spring自带的 SimpleAsyncTaskExecutor 线程池,会不断的创建线程,当并发大的时候会严重影响性能。

1、@Async简介

@Async是一个注解,其作用就是加上该注解的类或方法能够异步执行任务,该注解添加到方法上时,表示该方法是异步方法,添加到类上时,表示该类中的所有方法都是异步方法。
当在使用@Async时,如果不指定具体的线程池名称,那么其使用的是默认线程池SimpleAsyncTaskExecutor。而该线程池的默认配置为(在TaskExecutionProperties中):

  • 核心线程数:8
  • 容量:Integer.MAX_VALUE
  • 最大线程数:Integer.MAX_VALUE
  • 空闲线程存活时间:60s
  • 允许核心线程超时:true

由上面的配置可知在并发量很大的情况下,其会没有限制的创建线程,当线程数量到达一定程度之后,就会影响相应的性能了。因此,在使用@Async注解时,最好使用自定义线程池,也就是在注解中添加自定义线程池的名字。

2、开启异步

启动类添加@EnableAsync开启异步,类似如下:

@EnableAsync
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

3、配置自定义线程池

配置类类似如下:

@EnableAsync
@Configuration
public class ThreadPoolConfig {
    /**
     * 线程池任务执行器
     * @return
     */
    @Bean
    public Executor taskExecutor() {
    	// 创建线程池
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心池大小
        executor.setCorePoolSize(5); 
        // 设置最大池大小,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(10); 
        // 设置队列容量
        executor.setQueueCapacity(100); 
        // 设置保持活动秒数,当超过了核心线程数之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60); 
        // 设置线程名称前缀
        executor.setThreadNamePrefix("myThread-"); 
        // 设置拒绝的执行处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

拒绝策略通常有四种:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
注:启动类或配置类需要加上@EnableAsync,开启异步。
线程池的运行机制如下:
在这里插入图片描述

4、@Async指定线程池

在@Async注解中直接指定线程池名称即可,类似如下:

@Async("taskExecutor")
    public void asyncTask() {
        // 逻辑代码...
        log.info("当前线程为:" + Thread.currentThread().getName());
    }

5、@Async失效可能原因

  • 启动类或线程池配置类没加@EnableAsync注解
  • 调用方法和@Async方法不要在一个类中
  • @Async方法的返回值只能是void和Future
  • @Async修饰的方法不能被static修饰
  • @Async修饰的的方法必须是public

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/918824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch Split和shrink API

背景: 尝试解决如下问题:单分片存在过多文档,超过lucene限制 分析 1.一般为日志数据或者OLAP数据,直接删除索引重建 2.尝试保留索引,生成新索引 - 数据写入新索引,查询时候包含 old_index,new_index 3.…

一、数据库基础

数据库 一、数据库基础 1、一些概念 数据库:数据库(DataBase ,简称DB),就是信息的集合。数据库是由数据库管理系统管理的数据的集合;数据库管理系统:简称DBMS 。是一种操纵和管理数据库的大型…

听GPT 讲Prometheus源代码--tsdb

题图来自 Prometheus TSDB (Part 1): The Head Block[1] tsdb 目录在 Prometheus 项目中承担了实现时间序列数据库(Time Series Database)的功能。Prometheus 使用这个自定义的时间序列数据库来高效地存储和查询监控数据。 在 tsdb 目录下,有…

这所C9无歧视!专业课简单,平均130分!

一、学校及专业介绍 哈尔滨工业大学(Harbin Institute of Technology,简称哈工大),是隶属于工业和信息化部的全国重点大学,位于哈尔滨市,九校联盟“C9”之一,位列国家“双一流”、“985工程”、…

连接未来 驱动创新|腾讯云 CODING DevOps 主题沙龙诚邀您的参与

点击链接了解详情 随着企业数字化转型步入深水区,DevOps 作为数字化转型关键的内建阶段,其应用和实施已经成为企业提升研发效率,实现快速迭代和持续交付的重要手段。然而如何有效地实施 DevOps,如何利用 DevOps 推动业务发展和创新…

Wireshark数据抓包分析之UDP协议

一、实验目的: 通过使用wireshark对UDP数据包的抓取分析UDP协议的内容 二、预备知识: UDP协议的概念:UDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接传输服务。它也不提供报文到达确认、排序及流量控制等功能。 …

kafka复习:(4)为什么默认情况下相同的key不为空的消息会被存储到相同的分区

默认分区器DefaultPartitioner的分区代码: 可以看到,消息最终落在哪个分区就是由总计有几个分区以及key的值来决定的。

EG3D: Efficient Geometry-aware 3D Generative Adversarial Networks [2022 CVPR]

长期以来,仅使用单视角二维照片集无监督生成高质量多视角一致图像和三维形状一直是一项挑战。现有的三维 GAN 要么计算密集,要么做出的近似值与三维不一致;前者限制了生成图像的质量和分辨率,后者则对多视角一致性和形状质量产生不…

推荐这11个平面设计软件,平面设计师必备好物

今天本文整理了大厂设计师都在用的平面设计软件,为设计师的平面设计工作高效赋能,一起来看看吧! 1、即时设计 即时设计是国内很多设计师或者设计团队都在用的平面设计软件,它能为个人设计师带来丰富的创作力和多样的平面设计功能…

UE学习记录03----UE5.2 使用拖拽生成模型

0.创建蓝图控件,自己想要展示的样子 1.侦测鼠标拖动 2.创建拖动操作 3.拖动结束时生成模型 3.1创建actor , 创建变量EntityMesh设为可编辑 生成Actor,创建变量EntityMesh设为可编辑 屏幕鼠标位置转化为3D场景位置 4.将texture设置为变量并设为可编辑&am…

ssm网上医院预约挂号系统源码和论文

ssm网上医院预约挂号系统源码和论文051 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 如今的信息时代,对信息的共享性,信息的流通性有着较高要求,因此传统管理方式…

SpringCloud教程 | 第五篇: 路由网关(zuul)

在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统。一个简单的微服务系统如下图: 注意&…

interview1-DB篇

需要项目经验可自行上Gitee寻找项目资源 一、Redis篇 1、缓存 缓存的要点可分为穿透、击穿、雪崩,双写一致、持久化,数据过期、淘汰策略。 (1)穿透、击穿、雪崩 1.缓存穿透 查询一个不存在的数据,mysql查询不到数据…

Ansible学习笔记(一)

1.什么是Ansible 官方网站:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html Ansible是一个配置管理和配置工具,类似于Chef,Puppet或Salt。这是一款很简单也很容易入门的部署工具,它使用SS…

Linux学习记录——이십오 多线程(2)

文章目录 1、理解原生线程库线程局部存储 2、互斥1、并发代码(抢票)2、锁3、互斥锁的实现原理 3、线程封装1、线程本体2、封装锁 4、线程安全5、死锁6、线程同步1、条件变量1、接口2、demo代码 1、理解原生线程库 线程库在物理内存中存在,也…

常用性能测试工具及其功能

在软件开发周期的不同阶段,性能测试工具被广泛用于评估系统的性能和发现潜在的性能瓶颈。本文介绍了几种常用的性能测试工具,包括负载测试工具、压力测试工具和基准测试工具,并详细描述了它们的功能和用法。 性能测试在软件开发的各个阶段都至…

SpringBoot 调用外部接口

SpringBoot 调用外部接口 一、第一种方式(HttpClient等) 使用插件方式,比如自带的HttpClient,或者OkHttp,甚至是原生的HttpURLConnection 等等,这里以HttpClient为例。 1、封装工具类 简单封装的get请求 /*** 发送get请求:带请求…

数字时代的先驱者,「Adobe之父」离世,享年82岁!

原创 | 文 BFT机器人 John Warnock于当地时间8月19日辞世,享年82岁。 他作为图形和出版软件公司Adobe的共同创始人,被誉为“Adobe之父”,在计算机图形学和电子出版等领域都做出了重大的贡献,为后人留下一笔丰厚的“遗产”&#x…

校园二手物品交易平台/二手交易系统/基于java的校园跳蚤市场系统

​ 摘 要 本文论述了校园二手物品交易平台的设计和实现,该网站从实际运用的角度出发,运用了计算机网站设计、数据库等相关知识,网络和Mysql数据库设计来实现的,网站主要包括用户注册、用户登录、浏览商品、搜索商品、查看商品并进…

8.23 类 构造函数 析构函数 拷贝构造函数

#include <iostream>using namespace std;class Per{string name;int age;float *high;float *weight; public:Per(string name,int age,float high,float weight):name(name),age(age),high(new float(high)),weight(new float(weight)){cout << "Per的构造函…