当前位置: 首页 > news >正文

Spring Boot简单多线程定时任务实现 | @Async | @Scheduled

Spring Boot简单多线程定时任务实现

实现步骤

1 创建一个Spring Boot项目

2 定义定时任务:

在这里插入图片描述

package com.jmd.timertasktest.task;import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;import java.time.LocalDateTime;/*** Created with IntelliJ IDEA.* User: Jiang* Time: 2023/12/24 024 21:53* File: TimerTaskUtil* Description:*/
@Configuration
@EnableScheduling  // 开启定时任务
@EnableAsync  // 开启多线程(异步)
public class TimerTaskTest {@Scheduled(cron = "0/5 * * * * ?")@Asyncpublic void testTimerTask1() throws InterruptedException {System.out.println("执行定时任务1 " + LocalDateTime.now());System.out.println("执行定时任务1的线程是-->" + Thread.currentThread().getName());Thread.sleep(10 * 1000);}@Scheduled(cron = "0/5 * * * * ?")@Asyncpublic void testTimerTask2() {System.out.println("执行定时任务2 " + LocalDateTime.now());System.out.println("执行定时任务2的线程是==>" + Thread.currentThread().getName());}}

在这里插入图片描述

执行定时任务1 2023-12-24T22:32:30.023176600
执行定时任务1的线程是-->task-1
执行定时任务2 2023-12-24T22:32:30.024173800
执行定时任务2的线程是==>task-2
执行定时任务2 2023-12-24T22:32:35.003081100
执行定时任务2的线程是==>task-3
执行定时任务1 2023-12-24T22:32:35.003081100
执行定时任务1的线程是-->task-4
执行定时任务1 2023-12-24T22:32:40.003165400
执行定时任务1的线程是-->task-5
执行定时任务2 2023-12-24T22:32:40.003165400
执行定时任务2的线程是==>task-6
执行定时任务2 2023-12-24T22:32:45.002857100
执行定时任务2的线程是==>task-7
执行定时任务1 2023-12-24T22:32:45.002857100
执行定时任务1的线程是-->task-8
执行定时任务1 2023-12-24T22:32:50.002249300
执行定时任务1的线程是-->task-2
执行定时任务2 2023-12-24T22:32:50.002966600

这种方式使用的是Spring默认的线程池SimpleAsyncTaskExecutor,Spring 使用 SimpleAsyncTaskExecutor 为每个任务生成一个新线程。(所以上面的运行结果可以发现sleep了10秒并不会影响定时任务的执行)

SimpleAsyncTaskExecutor 的缺点:默认的 SimpleAsyncTaskExecutor 为每个任务创建一个全新的线程,没有任何限制。在并发执行大量任务的情况下,这可能会导致系统资源耗尽。

解决方法(实现对线程创建和管理的细粒度控制):

  1. 可以在yml或properties中添加线程池配置

    spring:task:execution:pool:max-size: 10core-size: 8# keep-alive: 60queue-capacity: 100thread-name-prefix: Async-task
    

    在这里插入图片描述

  2. 使用ThreadPoolTaskExecutor

    package com.jmd.timertasktest.configuration;import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.AsyncConfigurer;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;/*** Created with IntelliJ IDEA.* User: Jiang* Time: 2023/12/24 024 23:43* File: TaskConfiguration* Description:*/
    @Configuration
    @EnableAsync
    public class TaskConfiguration implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5); // 核心线程数executor.setMaxPoolSize(10); // 最大线程数executor.setQueueCapacity(25); // 阻塞队列长度executor.setThreadNamePrefix("Async-");executor.initialize();return executor;}
    }
    

    在这里插入图片描述

@Async

Spring中的@Async注解是一种声明性方式,表示方法应该异步运行,即在单独的线程中运行,允许调用者继续执行而无需等待被调用方法的完成。

当使用 @Async 注解一个方法时,Spring 在背后执行以下操作:

  1. 它在启动时会给调用类创建一个代理
  2. 每当调用带有 @Async 注解的方法时,Spring 都会确保方法执行是由线程池中的线程执行的,从而允许调用方法毫不延迟地继续进行。

注意:

调用一个被@Async注解修饰的方法时,程序是不会等待方法执行的,直接执行下一个操作,缩短了响应时间,该方法通过线程池中的线程去执行了。

@Scheduled

@Scheduled注解是Spring Boot提供的用于定时任务控制的注解,主要用于控制任务在某个指定时间执行,或者每隔一段时间执行。注意需要配合@EnableScheduling使用,@Scheduled主要有4种配置执行时间的方式:

  • cron
  • fixedRate
  • fixedDelay
  • initialDelay
  1. corn

    语法(年非必填):

    [] [] [小时] [] [] [] []
    

在这里插入图片描述

通配符说明:
  • * 表示所有值。 例如:在分的字段上设置 *,表示每一分钟都会触发。
  • ? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为”?” 具体设置为 0 0 0 10 * ?
  • - 表示区间。例如 在小时上设置 “10-12”,表示 10,11,12点都会触发。
  • , 表示指定多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发
  • / 用于递增触发。如在秒上面设置”5/15” 表示从5秒开始,每增15秒触发(5,20,35,50)。 在日字段上设置’1/3’所示每月1号开始,每隔三天触发一次。
  • L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于”7”或”SAT”。如果在”L”前加上数字,则表示该数据的最后一个。例如在周字段上设置”6L”这样的格式,则表示“本月最后一个星期五”
  • W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上置”15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,”W”前只能设置具体的数字,不允许区间”-“)。
  • # 序号(表示每月的第几个周几),例如在周字段上设置”6#3”表示在每月的第三个周六.注意如果指定”#5”,正好第五周没有周六,则不会触发该配置(用在母亲节和父亲节再合适不过了) ;小提示:’L’和 ‘W’可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发;周字段的设置,若使用英文字母是不区分大小写的,即MON与mon相同。
  1. fixedRate

    @Scheduled(fixedRate = 5000) //上一次开始执行时间点之后5秒再执行
    @Scheduled(fixedRateString = "5000")
    
  2. fixedDelay

    @Scheduled(fixedDelay = 5000) //上一次执行完毕时间点之后5秒再执行
    @Scheduled(fixedDelayString = "5000") //上一次执行完毕时间点之后5秒再执行
    
  3. initialDelay

    @Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次
    @Scheduled(initialDelayString= "1000", fixedRate=5000)
    

线程池的执行:

在这里插入图片描述

相关文章:

Spring Boot简单多线程定时任务实现 | @Async | @Scheduled

Spring Boot简单多线程定时任务实现 实现步骤 1 创建一个Spring Boot项目 2 定义定时任务: package com.jmd.timertasktest.task;import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.Async; impor…...

sklearn学习的一个例子用pycharm jupyter

环境 运行在jupyter 进行开发。即一个WEB端的开发工具。能适时显示开发的输出。后缀用的是ipynb.pycharm也可以支持。但也要提示按装jupyter. 或直接用andcoda 这里我们用pycharm进行项目创建 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jupyterlab pip ins…...

JVM的生命周期

1.加载(Loading): 在加载阶段,JVM会找到并加载Java字节码文件。加载阶段分为三个步骤:通过类的全限定名找到对应的字节码文件,创建一个与该类相关的Class对象,将类的静态数据结构存储在方法区中…...

ElasticSearch--基本操作

ElasticSearch 完成ES安装 http://101.42.93.208:5601/app/dev_tools#/console 库的操作 创建索引库 请求方式:PUT 请求路径:/索引库名,可以自定义 请求参数:mapping映射 PUT /test {"mappings": {"propertie…...

大数据应用发展史:从搜索引擎时代到机器学习时代

文章目录 搜索引擎时代数据仓库时代数据挖掘时代机器学习时代小结 大数据技术的使用经历了一个发展过程 从最开始的Google在搜索引擎中开始使用大数据技术,到现在无处不在的各种人工智能应用,伴随着大数据技术的发展,大数据应用也从曲高和寡…...

java基础之String的不可变性

目录 概述 String是如何实现不可变的 String为何设计成不可变的 1.缓存和性能优化 2.安全性 3.线程安全性 4.API设计和预测性能 概述 String类的不可变性意味着一旦创建了一个字符串对象,它的值就不能被修改。 String是如何实现不可变的 查看源码 public …...

【JS】Promise详解

概述 在 JavaScript 中,Promise 是一个表示异步操作最终完成或失败的对象。它本质上是一个返回的对象,你可以附加回调函数,而不是将回调传递给函数。 let promise new Promise((resolve, reject) > {let condition true; // 这可以是某…...

原生微信小程序如何动态配置主题颜色及如何调用子组件的方法

一、最终效果 二、步骤 1、在初始化进入项目时,获取当前主题色 2、把主题色定义成全局变量(即在app.js中设置) 3、tabBar也需要定义全局变量,在首页时需要重新赋值 三、具体实现 1、app.js onLaunch () {//获取主题数据this.set…...

Java关键字(1)

Java中的关键字是指被编程语言保留用于特定用途的单词。这些关键字不能用作变量名或标识符。以下是Java中的一些关键字: public:表示公共的,可以被任何类访问。 private:表示私有的,只能被定义该关键字的类访问。 cl…...

【机器学习合集】深度生成模型 ->(个人学习记录笔记)

深度生成模型 深度生成模型基础 1. 监督学习与无监督学习 1.1 监督学习 定义 在真值标签Y的指导下,学习一个映射函数F,使得F(X)Y 判别模型 Discriminative Model,即判别式模型,又称为条件模型,或条件概率模型 生…...

Java将PDF转换为文本

在Java中&#xff0c;你可以使用现有的库来将PDF文件转换为文本。下面是一个简单的示例&#xff0c;使用Apache PDFBox库来实现PDF到文本的转换。首先&#xff0c;确保在你的项目中添加了Apache PDFBox库的依赖。你可以在 Maven 项目中添加以下依赖&#xff1a; <!--Pdf--&g…...

Linux 运维工具之1Panel

一、1Panel 简介 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。 特点&#xff1a; 快速建站&#xff1a;深度集成 Wordpress 和 Halo&#xff0c;域名绑定、SSL 证书配置等一键搞定&#xff1b;高效管理&#xff1a;通过 Web 端轻松管理 Linux 服务器&#xff0…...

深入了解小红书笔记详情API:为内容创新提供动力

一、小红书笔记详情API简介 小红书笔记详情API是一种允许开发者访问小红书平台上的笔记详细数据的接口。通过这个API&#xff0c;我们可以获取笔记的标题、内容、标签、点赞数、评论数等详细信息。这些数据对于内容创作者和品牌来说至关重要&#xff0c;可以帮助他们了解用户喜…...

Animate 2024(Adobe an2024)

Animate 2024是一款由Adobe公司开发的动画和互动内容创作工具&#xff0c;是Flash的演进版本。Animate 2024为设计师和开发者提供了更丰富的功能&#xff0c;让他们能够创建各种类型的动画、交互式内容和多媒体应用程序。 Animate 2024具有以下特点&#xff1a; 强大的设计工…...

尽量避免删改List

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…...

【Linux操作系统】探秘Linux奥秘:用户、组、密码及权限管理的解密与实战

&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《操作系统实验室》&#x1f516;诗赋清音&#xff1a;柳垂轻絮拂人衣&#xff0c;心随风舞梦飞。 山川湖海皆可涉&#xff0c;勇者征途逐星辉。 目录 &#x1fa90;1 初识Linux OS &…...

计算机组成原理复习4

习题 练习题 下列不属于系统总线的为&#xff08;&#xff09; a.数据总线 b.地址总线 c.控制总线 d.片内总线 D 系统总线中地址总线的功能是&#xff08;&#xff09; a.选择主存单元地址 b.选择进行信息传输的设备 c.选择外存地址 d.指定主存和I/O设备接口电路的地址 D 解…...

AutoSAR(基础入门篇)3.3-Autosar中RTE的数据一致性与Interface接口

目录 一、RTE的数据一致性 1、什么是数据一致性 2、数据一致性的实现机制 2.1、利用RTE管理<...

超维空间S2无人机使用说明书——52、初级版——使用PID算法进行基于yolo的目标跟踪

引言&#xff1a;在实际工程项目中&#xff0c;为了提高系统的响应速度和稳定性&#xff0c;往往需要采用一定的控制算法进行目标跟踪。这里抛砖引玉&#xff0c;仅采用简单的PID算法进行目标的跟随控制&#xff0c;目标的识别依然采用yolo。对系统要求更高的&#xff0c;可以对…...

<JavaEE> TCP 的通信机制(一) -- 确认应答 和 超时重传

目录 TCP的通信机制的核心特性 一、确认应答 1&#xff09;什么是确认应答&#xff1f; 2&#xff09;如何“确认”&#xff1f; 3&#xff09;如何“应答”&#xff1f; 二、超时重传 1&#xff09;丢包的概念 2&#xff09;什么是超时重传&#xff1f; 3&#xff09…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...