一文详解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
    • 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

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

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

在这里插入图片描述


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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32——CAN协议

文章目录 一.CAN协议的基本特点1.1 特点1.2 电平标准1.3 基本的五个帧1.4 数据帧 二.数据帧解析2.1 帧起始和仲裁段2.2 控制段2.3 数据段和CRC段2.4 ACK段和帧结束 三.总线仲裁四.位时序五.STM32CAN控制器原理与配置5.1 STM32CAN控制器介绍5.2 CAN的模式5.3 CAN框图 六 手册寄存…

智能优化算法应用:基于材料生成算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于材料生成算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于材料生成算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.材料生成算法4.实验参数设定5.算法结果6.…

【内存泄漏】内存泄漏及常见的内存泄漏检测工具介绍

内存泄漏介绍 什么是内存泄漏 内存泄漏是指程序分配了一块内存(通常是动态分配的堆内存),但在不再需要这块内存的情况下未将其释放。内存泄漏会导致程序浪费系统内存资源,持续的内存泄漏还导致系统内存的逐渐耗尽,最…

Kafka日志

位置 server.properties配置文件中通过log.dir指定日志存储目录 log.dir/{topic}-{partition} 核心文件 .log 存储消息的日志文件,固定大小为1G,写满后会新增一个文件,文件名表示当前日志文件记录的第一条消息的偏移量。 .index 以偏移…

【SpringCloud笔记】(8)服务网关之GateWay

GateWay 概述简介 官网地址: 上一代网关Zuul 1.x:https://github.com/Netflix/zuul/wiki(有兴趣可以了解一下) gateway:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/…

讲座思考 | 周志华教授:新型机器学习神经元模型的探索

12月22日,有幸听了南京大学周志华教授题为“新型机器学习神经元模型的探索”的讲座。现场热闹非凡,大家像追星一样拿着“西瓜书”找周教授签名。周教授讲得依旧循循善诱,由浅入深,听得我很入迷,故作此记。 周教授首先就…

Python电能质量扰动信号分类(二)基于CNN模型的一维信号分类

目录 前言 1 电能质量数据集制作与加载 1.1 导入数据 1.2 制作数据集 2 CNN-2D分类模型和训练、评估 2.1 定义CNN-2d分类模型 2.2 定义模型参数 2.3 模型结构 2.4 模型训练 2.5 模型评估 3 CNN-1D分类模型和训练、评估 3.1 定义CNN-1d分类模型 3.2 定义模型参数 …

【已解决】Python Bresenham 3D算法

放一段使用Python实现Bresenham 3D 算法的代码,并通过Matplot可视化 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from numba import njitnjit def bresenham_safe(grid, x0, y0, z0, x1, y1, z1, value_to_fill…

锯齿云服务器租赁使用教程

首先登陆锯齿云账号 网盘上传数据集与代码 随后我们需要做的是将所需要的数据集与代码上传到网盘(也可以直接在租用服务器后将数据集与代码传到服务器的硬盘上,但这样做会消耗大量时间,造成资源浪费) 点击工作空间:…

谷粒商城-商品服务-新增商品功能开发(商品图片无法展示问题没有解决)

在网关配置路由 - id: member_routeuri: lb://gulimemberpredicates:- Path/api/gulimember/**filters:- RewritePath/api/(?<segment>.*),/$\{segment}并将所有逆向生成的工程调式出来 获取分类关联的品牌 例如&#xff1a;手机&#xff08;分类&#xff09;-> 品…

力扣经典面试题——搜索二维矩阵(两次二分搜索)

https://leetcode.cn/problems/search-a-2d-matrix/description/?envTypestudy-plan-v2&envIdtop-100-liked 思路&#xff1a;先按行二分&#xff0c;再按列进行二分。即先找到对应的行&#xff0c;再找对应的列。 对于这种判断是否存在某个数&#xff0c;记得while(left…

优化模型:MATLAB整数规划

一、整数规划介绍 1.1 整数规划的定义 若规划模型的所有决策变量只能取整数时&#xff0c;称为整数规划。若在线性规划模型中&#xff0c;变量限制为整数&#xff0c;则称为整数线性规划。 1.2 整数规划的分类 整数规划模型大致可分为两类&#xff1a; &#xff08;1&…