一文详解SpringBoot 定时任务(cron表达式)

IDE:IntelliJ IDEA 2022.2.3 x64
操作系统:win10 x64 位 家庭版
JDK: 1.8


文章目录

  • 一、如何开启一个SpringBoot定时任务?
  • 二、cron表达式详解
    • 2.1 语法格式
    • 2.2 符号解析
      • 2,2.1 通用符号: , - * /
      • 2.2.2 专有符号:?L w # c
    • 2.3 测试运行
  • 三、fixedRate & fixedDelay
    • 3.1 fixedRate
    • 3.2 fixedDelay
  • 四、如何异步多线程的执行SprigBoot定时任务?
  • 资料参考


提示:以下是本篇文章正文内容,下面案例可供参考

一、如何开启一个SpringBoot定时任务?

在我们日常开发中,开启并使用一个SpringBoot定时任务的大致步骤通常按如下所示

步骤

①在启动类上添加@EnableScheduling开启定时任务

示例代码如下

//开启定时任务
@EnableScheduling
@SpringBootApplication
public class MySpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }

}

②编写定时任务,在其上添加@Scheduled设置任务执行时间

示例代码如下

 //每3秒执行一次
    @Scheduled(fixedRate = 3000)
    public void notifyA(){
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }

③将定时任务所在的类上添加@Component

示例代码如下

@Component
public class springTimerTask {

    //每3秒执行一次
    @Scheduled(fixedRate = 3000)
    public void notifyA(){
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }
}

运行如下

在这里插入图片描述


二、cron表达式详解

在日常开发中,可以借助下面的网站快速生成cron表达式,提高开发效率

👉cron表达式在线生成器

2.1 语法格式

形式*******
字段SecondsMinutesHoursDayofMonthMonthDayofWeekYear
含义星期年(可选)
范围0-590-590-231-311-12(JAN-DEC)1-7 (SUN-SAT)
符号, - * /, - * /, - * /, - * /, - * / ? L C #, - * /, - * / ? L C #

备注

DayofWeek字段有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一,余下依次类推
Year字段有效范围为1970-2099年

2.2 符号解析

2,2.1 通用符号: , - * /

  • ,表示列出枚举值。例如:在Minutes域使用5,20,表示在时间的分钟数为5、20时触发事件
  • -表示范围。例如在Minutes域使用5-20,表示在时间的分钟数为5到20时每分钟都触发事件
  • *表示匹配该域的任意值。假如在Minutes:域使用,表示时间分钟数不做限制,每分钟都触发事件
  • /表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,表示时间的分钟数为5时触发一次,后隔20分钟即25、45再分别触发一次事件

举例说明

  • 0/2 * * * * ? : 表示每2秒 执行任务
  • 0 0/2 * * * ?表示每2分钟 执行任务
  • 0 0 2 1 * ?表示在每月的1日的凌晨2点调整任务

2.2.2 专有符号:?L w # c

  • ?只能用在DayofMonth和DayofWeek两个域,由于DayofMonthi和DayofWeek互斥,须对其一设置?
  • L表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用L,意味着在最后的一个星期四触发
  • W表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件
  • WL这两个字符可以连用,表示在某个月最后一个工作日
  • #用于确定每个月第几个星期几,只能出现在DayofWeek域。例如在4#2,表示某月的第二个星期三
  • C只能用在DayofMonth和DayofWeeki两个域,需要关联日历,如果没关联可以忽略

举例说明

  • 0 0-5 14 * * ? : 在每天下午2点到下午2:05期间的每1分钟触发
  • 0 10,44 14 ? 3 WED : 每年三月的星期三的下午2:10和2:44触发
  • 0 15 10 ? * MON-FRI : 周一至周五的上午10:15触发
  • 0 15 10 15 * ? : 每月15日上午10:15触发
  • 0 15 10 L * ? : 每月最后一日的上午10:15触发
  • 0 15 10 ? * 6L : 每月的最后一个星期五上午10:15触发
  • 0 15 10 ? * 6L 2002-2005: 2002年至2005年的每月的最后一个星期五上午10:15触发

注意

springBoot只支持cron表达式中的专有符号?,也仅仅支持6位的cron表达式,7位的不支持!!!

2.3 测试运行

示例代码如下

 //每2秒执行一次
    @Scheduled(cron = "0/2 * * * * ?")
    public void notifyA(){
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }

运行如下

在这里插入图片描述


三、fixedRate & fixedDelay

如下可知,@Schedule里还可以使用以下两种类型的表达式,分别是“fixedDelay = xxx” 与 “fixedRate = xxx”
在这里插入图片描述

3.1 fixedRate

fixedRate属性是@Schedule注解中的一个属性,它表示以固定的频率执行某个方法或任务。此属性用于指定任务执行的时间间隔,单位为毫秒。

例如,如果设置为2000(即2秒),则任务将每隔2秒执行一次。

示例代码如下

//每2秒执行一次
    @Scheduled(fixedRate = 2000)
    public void notifyB(){
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }

运行如下

在这里插入图片描述

注意

fixedRate是从上一次方法执行开始的时间算起,如果上一次方法阻塞住了,下一次也是不会执行,但是在阻塞这段时间内累计应该执行的次数,当不再阻塞时,一下子把这些全部执行掉,而后再按照固定速率继续执行。

测试代码如下

	//模拟任务阻塞4s,每2秒执行一次
    @Scheduled(fixedRate = 2000)
    public void notifyB() throws InterruptedException {
        Thread.sleep(4000);
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }

运行如下

在这里插入图片描述

3.2 fixedDelay

fixedDelay属性是@Schedule注解中的一个属性,它表示以固定的时间间隔执行某个方法或任务,并在每次执行完成后等待指定的延迟时间再执行下一次。

fixedDelay属性用于指定任务执行之间的延迟时间,单位为毫秒。

例如,如果设置为2000(即2秒),则任务将每隔2秒执行一次,并且在每次执行完成后等待2秒再执行下一次。

示例代码如下

   //每2秒执行一次,并延迟2s
    @Scheduled(fixedDelay = 2000)
    public void notifyB(){
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }

运行如下

在这里插入图片描述

注意

fixedDelay的执行时间是以上一次方法执行完开始算起,比如上一次方法执行阻塞住了,那么直到上一次执行完,并间隔给定的时间后,执行下一次

举个具体的例子,如果在一个方法上设置了fixedDelay=5*1000(即5秒),那么当该方法某一次执行结束后,开始计算时间,当时间达到5秒,就开始再次执行该方法。这意味着无论任务实际执行需要多长时间,每个任务之间的延迟时间始终保持不变。

测试代码如下

	//模拟上次任务阻塞4s,然后间隔2秒执行下一次
    @Scheduled(fixedDelay = 2000)
    public void notifyB() throws InterruptedException {
        Thread.sleep(4000);
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }

运行如下

在这里插入图片描述


四、如何异步多线程的执行SprigBoot定时任务?

最简单的做法如下所示

步骤

①在启动类上添加注解@EnableAsync开启异步执行

示例代码如下

@EnableScheduling
@SpringBootApplication
@EnableAsync
public class MySpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }

}

②在定时任务上添加@Asynci设置异步执行

示例代码如下

@Component
public class springTimerTask {

    //每2秒执行一次
    @Async
    @Scheduled(cron = "0/2 * * * * ?")
    public void notifyA(){
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }


    //每3秒执行一次
    @Async
    @Scheduled(cron = "0/3 * * * * ?")
    public void notifyB() throws InterruptedException {
        String now = new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
        String name = Thread.currentThread().getName();
        System.out.println(name+"通知已发送"+",发送时间为"+now);
    }
}

运行如下

在这里插入图片描述

why?

Spring默认单线程的定时任务,如果不开启异步,多个任务都是同一个线程在处理,如果这个线程内的任务比较耗时,会导致后续任务延期; 开启异步后,每个任务都会从线程池里分配一个线程去完成,避免耗时长的任务,导致其他任务延期,故而上述代码在中存在多个线程在执行同一个任务的情况;

不信?请看如下不开启异步,多个定时任务同时运行的情形

在这里插入图片描述


资料参考

https://www.bilibili.com/video/BV1JR4y1N7Ni/?p=7&spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=5a34715e416a427a73a3ca52397848b5

https://blog.csdn.net/u011066470/article/details/107529863?ops_request_misc=&request_id=&biz_id=102&utm_term=SpringBoot%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1:%20cron%E8%A1%A8%E8%BE%BE%E5%BC%8F&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-107529863.142v96pc_search_result_base9&spm=1018.2226.3001.4187

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux操作系统——进程(四)进程切换与命令行参数

进程切换 概念引入 下面我们先了解几个概念: 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级 独立性: 多进程…

关于Smartbi登录代码逻辑漏洞的动态情报

一、基本内容 近日,思迈特软件核查发现存在“登录代码逻辑漏洞”问题,重点影响范围涉及Smartbi V9及其以上版本。该漏洞可能导致攻击者利用逻辑缺陷对目标系统进行攻击,造成敏感信息泄露和远程代码执行的风险。 二、相关发声情况 Smartbi是…

科技巨头的选择:为何不跟风用钉钉和企业微信?

引言 大家好,我是你们的小米!今天,我想和大家聊一聊一个很有趣的话题——为什么大厂不同钉钉、企业微信等软件而自主研发IM(即时通讯)呢?难道这些明星产品还有什么不足之处?让我们一起揭开这个…

lv13 环境搭建之内核编译 4

一、开发板运行Linux 1. 网线连接开发板和主机 2. ubuntu下拷贝uImage、exynos4412-fs4412.dtb两个文件到/tftpboot目录下cd ~/fs4412cp uImage exynos4412-fs4412.dtb /tftpboot 3. rootfs.tar.xz解压到/opt/4412sudo tar xvf rootfs.tar.xz -C /opt/4412sudo chmod 777 /opt…

项目中关于地理位置相关需求的实现思路

实现思路:通过Redis中的GEO数据结构进行实现 一、GEO命令: 1.命令示例: GEOADD g1 116.378248 39.865275 bjn 116.42803 39.903738 bjz 116.322287 39.893729 bjx输出结果: 2.计算bjx(北京西站)到bjn&…

leetcode 6. N 字形变换(medium)(优质解法)

链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 代码: class Solution {public String convert(String s, int numRows) {if(numRows 1) {return s;}int lengths.length();StringBuilder retnew StringBuilder();//获取…

【MATLAB】史上最全的17种信号分解+FFT+HHT组合算法全家桶

有意向获取代码,请转文末观看代码获取方式~ 1 【MATLAB】EMD 信号分解算法 EMD 是一种信号分解方法,它将一个信号分解成有限个本质模态函数 (EMD) 的和,每个 EMD 都是具有局部特征的振动模式。EMD 分解的主要步骤如下: 将信号的…

HTTP 原理

HTTP 原理 HTTP 是一个无状态的协议。无状态是指客户机(Web 浏览器)和服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后服务器返回响应(response),连接就被关闭了,在服务器端…

微短剧,会成为长视频的“救命稻草”吗?

职场社畜秒变霸道总裁,普通女孩穿越成为艳丽皇妃.......这样“狗血”的微短剧,最近不仅在国内各大视频平台上异常火爆,而且还直接火出了国外。 所谓微短剧,就是单集时长从几十秒到十几分钟的剧集,有着相对明确的主题和…

sql_lab之sqli中的宽字节注入(less32)

宽字节注入(less-32) 1.判断注入类型 http://127.0.0.3/less-32/?id1 http://127.0.0.3/less-32/?id1 出现 \’ 则证明是宽字节注入 2.构成闭环 http://127.0.0.3/less-32/?id1%df -- s 显示登录成功则构成闭环 3.查询字段数 http://127.0.0.3/…

SpringMVC:整合 SSM 下篇

文章目录 SpringMVC - 05整合 SSM 下篇一、设计页面1. 首页:index.jsp2. 展示书页面:showBooks.jsp3. 增加书页面:addBook.jsp4. 修改书页面:updateBook.jsp5. 总结 二、控制层1. 查询全部书2. 增加书3. 修改书4. 删除书5. 搜索书…

Leetcode—86.分隔链表【中等】

2023每日刷题(六十九) Leetcode—86.分隔链表 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* partition(struct ListNode* head, int x) {struct ListNode…

Arduino平台软硬件原理及使用——PWM脉宽调制信号的原理及使用

文章目录: 一、先看百度百科给出的定义及原理 二、一图看懂PWM脉宽调制原理 三、Arduino中PWM脉宽调制信号的使用 一、先看百度百科给出的定义及原理 脉冲宽度调制是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,…

C预处理 | pragma详解

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和…

pci_enable_device()

前言 在 PCI 总线下,当 PCIe 设备和 PCIe 驱动匹配后,就会执行驱动的 probe() 函数来初始化设备,以让设备正常运行。 在 probe() 函数中,最先做的事情就是执行 pci_enable_device() 来使能设备。如果设备都无法使能的话&#xff…

MES系统是什么?MES系统的功能有哪些?

在现代制造业的快速发展中,所有规模的企业都面临着类似的挑战:如何提高生产效率、确保产品质量、减少浪费、降低成本,同时迅速响应市场变化。而在这个过程中,传统企业管理往往有以下几个典型痛点: 纸质文件堆叠如山&a…

框架面试题

文章目录 1. spring中的bean是线程安全的吗2. 事务的实现--AOP3. 项目中用到的AOP4.spring中事务的失效场景5. Bean的生命周期6.spring中的循环引用问题7. springMVC的执行流程8. springboot自动装配原理9. 常见注解10 Mybatis11 Mybatis一二级缓存 1. spring中的bean是线程安全…

约束-练习题

练习1 已经存在数据库test04_emp,两张表emp2和dept2 CREATE DATABASE test04_emp; use test04_emp; CREATE TABLE emp2( id INT, emp_name VARCHAR(15) ); CREATE TABLE dept2( id INT, dept_name VARCHAR(15) );题目: 向表emp2的id列中添加PRIMARY KEY约束向表d…

前端---css 的介绍

1. css 的定义 css(Cascading Style Sheet)层叠样式表,它是用来美化页面的一种语言。 没有使用css的效果图 使用css的效果图 2. css 的作用 美化界面, 比如: 设置标签文字大小、颜色、字体加粗等样式。控制页面布局, 比如: 设置浮动、定位等样式。 3. css 的基本语…

【2024 行人重识别最新进展】ReID3D:首个关注激光雷达行人 ReID 的工作!

【2024 行人重识别最新进展】ReID3D:首个关注激光雷达行人 ReID 的工作! 摘要:数据集:方法模型:多任务预训练:ReID Network: 实验结果:结论: 来源:Arxiv 2023…