定时任务框架Quartz

article/2025/9/24 2:22:02

目录

一、Quartzh介绍

        1、Quartz的定义:

        2、Quartz完成定时任务的原理:

二、cron表达式

          1、cron表达式定义

          2、cron表达式规范 

三、spring自带调度器

四、Quartz内存版集成基本使用

        1、关于Quartz内存版集成的步骤

                 1、先到启动类中写好集成的步骤

                 2、再写一个任务类

                 3、优化Quartz内存方式

                 4、测试结果​

五、关于Job任务和Trigger触发器的介绍

        1、Job任务

                  1、定义

                  2、实例化的过程

        2、Trigger触发器

                 2.1介绍

                 2.2触发器常用属性

                 2.3触发器的优先级 

                 2.4常用触发器 在第四大点已经讲解到


一、Quartzh介绍

        1、Quartz的定义:

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:

持久性作业 - 就是保持调度定时的状态;
作业管理 - 对调度作业进行有效的管理;

每周末凌晨备份数据

触发条件 5 分钟后发送邮件通知

30 分钟未支付取消订单

每 1 小时去拉取数据

        2、Quartz完成定时任务的原理:

        1、首先我们需要定义实现一个定时功能的接口,称之为Task(或Job),如定时发送邮件的task(Job),重启机器的task(Job),优惠券到期发送短信提醒的task(Job),实现接口如下:

        2、有了任务之后,还需要一个能够实现触发任务去执行的触发器,触发器Trigger最基本的功能是指定Job的执行时间,执行间隔,运行次数等。 

        3、有了Job和Trigger后,怎么样将两者结合起来呢?即怎样指定Trigger去执行指定的Job呢?这时需要一个Schedule,来负责这个功能的实现。 

由以上原理可得Quartz可以由以下三部分组成

  • 调度器:Scheduler
  • 任务:JobDetail
  • 触发器:Trigger,包括SimpleTrigger(简单触发器)和CronTrigger

二、cron表达式

          1、cron表达式定义

cron表达式是一个字符串,以5或者6个空格隔开(示例中是被5个空格隔开),字符串被切割为6个或者7个域,每个域都代表不同的含义

          2、cron表达式规范 

秒 分 小时 天数 月 星期 年 

{Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek} {Year}

{Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek}

每个域都可以用数字表示,还可以出现如下特殊字符 

* : 表示匹配该域的任意值,比如Minutes域使用*,就表示每分钟都会触发

- : 表示范围,比如Minutes域使用10-20,就表示从10分钟到20分钟每分钟都会触发一次

, : 表示列出枚举值,比如Minutes域使用1,3.就表示1分钟和3分钟都会触发一次

/ : 表示间隔时间触发(开始时间/时间间隔),例如在Minutes域使用 5/10,就表示从第5分钟开始,每隔10分钟触发一次

? : 表示不指定值,简单理解就是忽略该字段的值,直接根据另一个字段的值触发执行

# : 表示该月第n个星期x(x#n),仅用星期域,如:星期:6#3,表示该月的第三个星期五

L : 表示最后,是单词"last"的缩写(最后一天或最后一个星期几);仅出现在日和星期的域中,用在日则表示该月的最后一天,用在星期则表示该月的最后一个星期,如:星期域上的值为5L,则表示该月最后一个星期的星期四,在使用'L'时,不要指定列表','或范围'-',否则易导致出现意料之外的结果

W: 仅用在日的域中,表示距离当月给定日期最近的工作日(周一到周五),是单词"weekday"的缩写

注意:天数和星期不能同时出现!!!

三、spring自带调度器

           1、创建一个简单项目(不要任何工具注入),将开启调度器注解注入启动类中

@EnableScheduling

           2、写一个任务类Task

package com.zj.code;import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;@Component
@Slf4j
public class Task {@Scheduled(fixedRate = 2000)//上⼀次开始执⾏时间点之后2秒再执⾏public void task(){log.warn("现在时间:" + LocalDateTime.now());}
}

关于调度器的几个注解:

@Scheduled(fixedRate=5000):上⼀次开始执⾏时间点之后5秒再执⾏@Scheduled(fixedDelay=5000):上⼀次执⾏完毕时间点之后5秒再执⾏@Scheduled(initialDelay=1000, fixedRate=5000):第⼀次延迟1秒后执⾏,之后按fixedRate的规则每5秒执⾏⼀次@Scheduled(cron="*/5 * * * * *"):通过cron表达式定义规则

           3、进行测试

四、Quartz内存版集成基本使用

        1、关于Quartz内存版集成的步骤

                 1、先到启动类中写好集成的步骤

//1、先实例化调度器工厂
//2、得到调度器
//3、创建任务
//4.创建触发器
//5.将触发器和任务绑定到调度器中去
//6.启动调度器
package com.zj.code;import org.junit.jupiter.api.Test;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Date;import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;@SpringBootTest
class Quartz01ApplicationTests {@Testvoid contextLoads() throws Exception {//1、先实例化调度器工厂SchedulerFactory factory = new StdSchedulerFactory();//2、得到调度器Scheduler scheduler = factory.getScheduler();//3、创建任务JobDetail jobDetail = newJob(MyJob.class).withDescription("开年大扫除").withIdentity("a", "b").usingJobData("name", "王阿姨").build();//4.创建触发器Trigger trigger = TriggerBuilder.newTrigger().withDescription("大扫除触发器").withIdentity("b", "c").startAt(new Date())
//                .withSchedule(
//                        simpleSchedule()
//                                .withIntervalInSeconds(1)
//                                .withRepeatCount(10) //SimpleTrigger.REPEAT_INDEFINITELY
//                )
//                .withSchedule(
//                        CronScheduleBuilder.cronSchedule("* * * * * ?")
//                ).build();//5.将触发器和任务绑定到调度器中去scheduler.scheduleJob(jobDetail, trigger);//6.启动调度器scheduler.start();}}

                 2、再写一个任务类

MyJob:
package com.zj.code;import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;/*** @author T440s*/
@Slf4j
public class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {Object name = context.getJobDetail().getJobDataMap().get("name");//先得到任务,之后就得到map中的名字log.warn(name + "搞卫生");}
}

                 3、优化Quartz内存方式

当我们做定时任务时,时常不能让他只执行一次,而是要在我指定时间去完成定时任务,这时候就涉及到常用触发器

触发器分为常用触发器和基于cron表达式的触发器

常用触发器:

Trigger trigger = TriggerBuilder.newTrigger()       
.withDescription("")       
.withIdentity("clean", "clean1")       
.startAt(new Date())       
.withSchedule(            simpleSchedule()               .withIntervalInSeconds(10)                .withRepeatCount(10) //SimpleTrigger.REPEAT_INDEFINITELY       
)       
.build();

基于cron表达式的触发器

Trigger trigger = TriggerBuilder.newTrigger()       .withIdentity("test", "test")       .withDescription("测试的触发器")       .withSchedule(CronScheduleBuilder.cronSchedule("2 * * * * *"))       .build();

                 4、测试结果

五、关于Job任务和Trigger触发器的介绍

        1、Job任务

                  1、定义

任务是一个实现 org.quartz.Job 接口的类,任务类必须含有空构造器当关联这个任务实例的触发器表明的执行时间到了的时候,调度程序 Scheduler 会调用这个方法来执行任务,任务内容就可以在这个方法中执行,JobDataMap 提供了一种“初始化成员属性数据的机制”,在实现该 Job 接口的时候可以取到需要的数据,就如第四点的Myjob类一样

package com.zj.code;import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;/*** @author T440s*/
@Slf4j
public class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {Object name = context.getJobDetail().getJobDataMap().get("name");//先得到任务,之后就得到map中的名字log.warn(name + "搞卫生");}
}

                  2、实例化的过程

创建一个 Job 类,在调度程序中可以创建很多个 JobDetai,分别设置不同的 JobDataMap,JobBuilder 用于创建 JobDetail,如果没有调用 withIdentity 指定 job 的名字,会自动生成一个。

JobDetail jobDetail = newJob(MyJob.class)               
.withDescription("开年大扫除")               
.withIdentity("大扫除", "厕所")               
.usingJobData("name", "王阿姨")               
.build();

        2、Trigger触发器

                 2.1介绍

触发器使用 TriggerBuilder 来实例化,有一个 TriggerKey 关联,在一个 Scheduler 中必须是唯一的。多个触发器可以指向同一个工作,但一个触发器只能指向一个工作。触发器可以传送数据给 job,通过将数据放进触发器的 JobDataMap。

                 2.2触发器常用属性

触发器也有很多属性,这些属性都是在使用 TriggerBuilder 定义触发器时设置的。TriggerKey,唯一标识,在一个 Scheduler 中必须是唯一的

startTime,开始时间,通常使用 startAt(java.util.Date)

endTime,结束时间,设置了结束时间则在这之后,不再触发

 Trigger trigger = TriggerBuilder.newTrigger()               
.withDescription("大扫除触发器")               
.withIdentity("大扫除", "厕所")               
.startAt(new Date())               
.build();

 如果没有使用 withIdentity(..) 会自动生成一个触发器名称。

                 2.3触发器的优先级 

有时候,会安排很多任务,但是 Quartz 并没有更多的资源去处理它。

这种情况下,必须需要很好地控制哪个任务先执行。这时候可以设置 priority 属性(使用方法withPriority(int))来控制触发器的优先级。

优先级只有触发器出发时间一样的时候才有意义。

当一个任务请求恢复执行时,它的优先级和原始优先级是一样的。

                 2.4常用触发器 在第四大点已经讲解到

今天的知识就分享到这了,希望对你有帮助! 


http://chatgpt.dhexx.cn/article/mgHxbkFU.shtml

相关文章

定时任务:Quartz 详解

定时任务:Quartz 详解 文章目录 定时任务:Quartz 详解1 Quartz是什么?2 Quartz核心组成3 Quartz核心模块理解3.1 用工厂模式理解 Quartz 的设计机制:3.2 用流程图理解 Quartz 的核心模块关系: 4 Quartz详解4.1 Quartz的…

Linux 环境下的 for循环嵌套学习

题目&#xff1a;输出下面的 4*5 的矩阵&#xff1a; 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 解: 首先打开Xfce终端&#xff0c;创建c文件&#xff0c; 并用gedit记事本打开它。 touch zhanglong.c gedit zhanglong.c之后输入代码&#xff1a; #include<std…

for循环嵌套编程练习

1 编程要求:求出用50元,20元和10元换算100元有几种方式? 思路:用穷举法,将所有可能的情况都列举出来,用for循环可以实现穷举 分析:100元单用50换算,最多需要两张,用20元最多换算5张,用10元最多换算10张 #include<stdio.h> int main(void) {int w,e,s; // w代表…

c语言99乘法表循环嵌套写法,99乘法表(for循环嵌套)

计算乘法表 两个数相乘,外层循环代表被乘数,控制行数;内层代表乘数,控制列数。 循环嵌套,变量名不可以重复。 使用 break 语句让输出的乘法表更简洁。 使用 String 变量,做 String 的加法。 public class MultiTabble {public static void main(String[] args) {for (int…

关于For循环嵌套的简单理解

一&#xff1a;循环语句的嵌套 一个循环结构内可以含有另一个循环&#xff0c;称为循环嵌套&#xff0c;又称多重循环。常用的循环嵌套是二重循环&#xff0c;外层循环称为 外循环&#xff0c;内层循环称为内循环。 二&#xff1a;双重循环&#xff1a; 1.双重循环结构 for (循…

for循环嵌套的三种用法

目前本人了解到的常用的三种for循环嵌套&#xff0c;以下是对这三种循环嵌套的理解&#xff1a; 一&#xff1a;内外循环联动 var arr [[10, 20, 30],[hello, hi, world],[a, b, c]]for (var i 0; i < arr.length;i){let innerArr arr[i];for(var j 0;j < innerArr…

多重for循环嵌套

for循环定义&#xff1a; 同过一个简单的表达式&#xff0c;来完成多次重复性的代码功能&#xff1b;格式如下&#xff1a; for&#xff08;变量初始值&#xff1b;变量取值范围&#xff1b;变量自增/自减&#xff09;{ //代码块&#xff1b; } 一个复杂的for循环中可以嵌…

JS中的for循环嵌套

for 循环 for语句也是一种前测试循环语句&#xff0c;但它具有在 执行循环之前初始化变量 和 定义循环后要执行的代码的能力 for循环中专门提供了位置来放置循环的三个表达式 定义一个循环需要做实现这三步&#xff1a; 1、初始化表达式 2、条件表达式 3、更新表达式 通…

【Python】循环语句 ⑦ ( for 循环嵌套 | continue 临时跳过本次循环 | break 结束循环 )

文章目录 一、for 循环嵌套1、for 循环嵌套语法2、for 循环嵌套 - range 简单示例3、for 循环嵌套 - 打印乘法表示例 二、continue 临时跳过本次循环1、continue 关键字简介2、代码示例 - continue 简单用法3、代码示例 - continue 在嵌套循环中使用 三、break 结束循环1、brea…

js中for循环嵌套

首先我们的for循环单个就是我们将内容全部输出出来执行的条件 1.首先声明初始值 2.设置条件 3.执行代码块 4.执行i 代码如下&#xff0c; <button type"button" onclick"tests()">测试10</button><div id"dom10"></d…

for循环,for循环嵌套

for循环 for(var i 0;i<10;i) for循环用于遍历对象&#xff0c;并将对象中的数拿出来 for循环的括号里用两个分号把它分成了三个部分&#xff0c;第一部分是循环变量&#xff0c;第二部分是循环的判断条件&#xff0c;第三部分是变量的变化规律&#xff08;即每循环一次变…

Java for循环和Java for循环嵌套详解

for 语句是应用最广泛、功能最强的一种循环语句。大部分情况下&#xff0c;for 循环可以代替 while 循环、do while 循环。 for 语句是一种在程序执行前就要先判断条件表达式是否为真的循环语句。假如条件表达式的结果为假&#xff0c;那么它的循环语句根本不会执行。for 语句…

Java for循环嵌套for循环,你需要懂的代码性能优化技巧

前言 本篇分析的技巧点其实是比较常见的&#xff0c;但是最近的几次的代码评审还是发现有不少兄弟没注意到。 所以还是想拿出来说下。 正文 是个什么场景呢&#xff1f; 就是 for循环 里面还有 for循环&#xff0c; 然后做一些数据匹配、处理 这种场景。 我们结合实例代码来…

Java for循环嵌套

一、需求 需求1&#xff1a;打印以下图形 **** **** **** for(int i 0;i<3;i){//控制行数for(int j 0;j<4;j){//控制列数System.out.print("*");}System.out.println(); } 需求2&#xff1a;打印以下图形 …

C语言for循环语句及嵌套(误区,易错点要理解)

目录 前言 例题1&#xff1a; 例题2&#xff1a; for循环中contiune的使用&#xff1a; 前言 大家好&#xff0c;相信刚学C语言的小白们&#xff0c;觉得for循环是比较好用的&#xff0c;但是有时候写for循环语句的程序时&#xff0c;写出来的代码结果&#xff0c;和自己想要…

for循环嵌套

文章目录 一、什么是循环嵌套&#xff1f;二、实例1.输出一个矩阵2.输出九九乘法表 一、什么是循环嵌套&#xff1f; 外层循环和内层循环交叉执行&#xff0c;外层 for 每执行一次&#xff0c;内层 for 就要执行符合循环条件的次数。 二、实例 1.输出一个矩阵 代码如下&…

44. python的for循环嵌套

44. python的for循环嵌套 文章目录 44. python的for循环嵌套1. 什么是嵌套2. for循环中嵌套有if条件判断语句2.1 先创建一个奇数序列2.2 判断一个数是否能被7整除2.3 将2部分代码合二为一 3. for循环中嵌套有for循环 1. 什么是嵌套 嵌套是指一个对象中包含另一个与它相似的对象…

【C语言初学必看】一知半解的for循环嵌套for循环

&#x1f525;&#x1f680;前言目录&#xff1a; 初学C语言&#xff0c;常常遇到for循环中嵌套个for循环&#xff0c;初学者对于这种形式总是一知半解&#xff0c;这次我就整理了常见的for循环嵌套for循环的题目&#xff0c;我们一起争取一举拿下这类题。学废他们&#xff0c;…

双重for循环(嵌套for循环)

什么是双重循环&#xff1f; 双重循环&#xff1a;我们从字面上理解它&#xff0c;就是有两个循环套在一起 详细解释 双重for循环就是在一个for循环里在嵌套另一个for循环&#xff0c;即两个循环嵌套&#xff0c;还有多重循环嵌套的情况&#xff0c;但用的比较少&#xff0c…

DRN ---Closed-loop Matters: Dual Regression Networks for Single Image Super-Resolution

Closed-loop Matters: Dual Regression Networks for Single Image Super-Resolution 这篇博客主要介绍一下DRN&#xff0c;这是2020年最新出来超分辨重建文章。相信大家都阅读过很多超分辨率的文章&#xff0c;都知道超分辨率是一病态的问题。因为在现实生活中一张低分辨率图…