Quartz定时任务基础学习

article/2025/9/24 2:21:31

Quartz基础笔记

前言

1、什么是Quartz

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目。

2、Quartz的运行环境是什么?

  • Quartz可以运行嵌入在一个独立式应用程序
  • Quartz可以在应用服务器或者Servlet容器实例化,并且参与事务
  • Quartz可以作为一个独立的程序运行在自己的Java虚拟架构中,可以通过RMI使用
  • Quartz可以被实例化,作为独立的项目集群(负载均衡或者故障转移功能),用于作业的执行

3、Quartz的运行环境

  • Builder模式
  • Factory模式
  • 组件模式
  • 链式编程

一、Quartz的核心概念

学习Quartz之前我们需要了解几个概念:

  1. Job(任务)

我们可以把这里Job理解为一个进程下的多个线程,Job表示一个工作,也就是执行具体业务逻辑的一个类,它里面就一个方法execuate

void execute(JobExecutionContext context) 
  1. JobDeatil(可执行的任务调度)

这里的JobDetail我么可以看作是一个封装的Job类,只有将具体的业务Job封装成JobDetail才可以被Quartz识别并调用。另外 JobDetail 还包含了这个任务调度的方案和策略。

  1. Trigger(触发器)

代表一个调度参数的配置,即我们时候去调用在Trigger里设置

  1. Scheduler(调度容器)

是一个整合JobDetail和Trigger的容器,一个Scheduler里可以放置多个JobDetail和Trigger

在这里插入图片描述

1.1 案例DEMO

由上图我们可以清楚的了解到,一个jobDetail是由JobBuilder创建,一个Trigger是由TriggerBuilder创建。而JobDetail和Trigger里可以创建对应的JobDataMap,往Map里加一些参数,供execuate方法里获取到对应的JobDataMap根据键获取到对应的属性值。

【引入依赖】

<dependencies><!-- Quartz核心包 --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency><!-- QUartz工具包 --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.3.2</version></dependency><!-- Log4j --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.12</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>
</dependencies>

【分析步骤】

  1. 由stdSchedulerFactory创建一个Scheduler
// 创建一个scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

可以通过scheduler获取到context(这里的context就是execuate里面的参数JobExecutionContext context),从而往里面设置一些属性

  1. 由scheduler创建对应的JobDetail和Trigger
// 创建JobDetail 由JobBuilder创建JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("myjob", "mygroup").usingJobData("j1", "jv1").build();job.getJobDataMap().put("j2", "jv2");// 创建Trigger 由TriggerBuilder创建Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").usingJobData("t1", "tv1").withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever()).build();trigger.getJobDataMap().put("t2", "tv2");

由scheduler创建的JobDetail和Trigger都支持链式编程,而且创建出来的JobDetail和Trigger都必须要添加一个属性withIdentity(String key,String value)

  1. 由scheduler添加创建出来的JobDetail和Trigger
scheduler.scheduleJob(JobDetail,Trigger);
  1. 启动Scheduler
scheduler.start();

在这里插入图片描述

如上图所示,Trigger每隔2s调用一次JobDetail执行Job所实现的Job真正的业务

上述示例是一个SimpleScheduler调度的。

1.2 Quartz核心API

Scheduler:与调度程序交互的接口

Job:你想要调度器执行的任务的组件所实现的接口

JobDetail:用于定义任务作业的示例

Trigger:触发器,用于定时调用JobDetail所封装的Job的组件

JobBuilder:构建JobDetail的示例的

TriggerBuilder:用于构建Trigger的示例的

1.3 Job和obDetail介绍

  • Job:工作任务调度的接口,任务类需要实现该接口,该接口中定义execuate方法,类似JDK的TimeTask类的run方法,在里面编写执行业务逻辑。
  • Job实例在Quartz中的生命周期,每次调度器执行完毕,他在调用execuate方法之前都会先创建一个新的Job实例,把原来的释放,释放的实力会被垃圾回收机制收回。
  • JobDetail:jobDetail实力提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定的Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
  • jobDetail重要属性:name,group,jobClass,jobDataMap

1.4 JobExecuateContext介绍

  • 当Scheduler调用一个Job的时候,就会将JobExecuateContext传递给Job的execuate()方法。
  • Job能通过JobExecuateContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。

1.5 JobDataMap介绍

(1)使用Map获取

  • 在进行任务调度的时候,JobDataMap存储在JobExecuationContext中,非常方便获取。
  • JbDataMap可以用来装载任何序列化的数据对象,当Job实例对象被执行时这些参数就会传递给它。
  • JobDataMap实现了JDK的Map接口,并且添加了非常方便的方法用来存取基本的数据类型。

1.6 有状态的Job和无状态的Job

通过@PersistJobDataAfterExecuation注解使用

有状态的Job可以理解为多次Job调用期间可以持有一些信息,这些状态信息存储在JobDetail里面,而默认的无状态的Job每次调用都会创建一个新的JobDataMap。

1.7 Trigger的详解

和Job一样,Trigger也和Trigger一样很好使用,但是Trigger有很多的类型,这里只详细学习一下SimpleTriggerCornTrigger两个核心的Trigger类型

1.7.1 Trigger的公共属性

注意:不管什么类型的Trgger,都有一个必须的属性:TriggerKey,用于唯一标识一个Trigger

除了TriggerKey以外,trigger还有一些公共属性。

  1. jobKey:当Trigger被触发的时候,执行的是哪一个Job
  2. startTime:开始触发的时间,该属性的值是一个java.util.Date类型的
  3. endTime:Trigger失效的时间点,比如说一个每个月的第五天执行的Trigger,假如他的endTime设置成7月1日,那么他最后一次执行的时间就是6月5日

1.7.2 Trigger的公共属性🔥🔥

SimpleTrigger可以满足的调度需求是:在具体的时间点执行一次,或者在具体的时间点执行,并且以指定的间隔重复执行若干次。比如,你有一个trigger,你可以设置它在2015年1月13日的上午11:23:54准时触发,或者在这个时间点触发,并且每隔2秒触发一次,一共重复5次。


SimpleTrigger的属性包括:开始时间、结束时间、重复次数以及重复的间隔。

  1. 开始时间:
  2. 结束时间
  3. 重复次数:可以是0、正整数,以及常量SimpleTrigger.REPEAT_INDEFINITELY
  4. 重复的间隔:必须是0,正整数
public class MainHelloTrigger {public static void main(String[] args) throws Exception {// 任务调度器 StdSchedulerFactoryScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();// 设置任务的开始时间Date startDate = new Date();// 延迟3s执行startDate.setTime(startDate.getTime()+3000);// 设置任务的结束时间Date endDate = new Date();endDate.setTime(endDate.getTime()+10000);// 调度任务实例JobDetail jobDetail = JobBuilder.newJob(HelloJobTrigger.class) 		// 加载任务类的实例.withIdentity("helloJob", "HelloJobGroup")			// 参数一:任务的名称(唯一实例);参数二:任务组的名称.build();// 触发器TriggerTrigger trigger = TriggerBuilder.newTrigger() 				// 创建一个触发器.withIdentity("HelloTrigger", "HelloTiggerGroup") 	// 参数一:触发器的名称;参数二:触发器的群组名
//				.startNow() // 马上启动触发器 只执行一次
//				.startAt(startDate) // 设置任务的开始时间.endAt(endDate)				.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) // 创建一个每5s重复执行一次的简单调度器 .build();// 获取触发器的名称以及组的名称 同理Job  如果不指定组名,按默认去执行  任务/触发器的名称必须要指明// 让调度器Scheduler关联触发器和任务scheduler.scheduleJob(jobDetail,trigger);// 启动scheduler调度任务scheduler.start();}
}

1.8 CronTrigger

CronTrigger通常比Simple Trigger更有用,如果您需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。

使用CronTrigger,您可以指定号时间表,例如“每周五中午”或“每个工作日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。

即使如此,和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。

二、Quartz配置

2.1配置、资源SchedularFactory

Quartz以模块方式架构,因此,要是他运行,几个组件必须很好二点聚合在一起,幸运的是,已经有了一些现存的助手可以完成这些工作。

所有的Schedular实例都是由SchedularFactory创建。

Quartz的三个核心概念,调度器,任务,触发器。三者之间的关系是:

在这里插入图片描述

大家都知道,一个作业,比较重要的三个参数就是Scheduler,jobDetail,Trigger;而Trigger对于JOB而言就是好比一个驱动器;没有触发器来定时驱动作业,作业就无法运行;对于JobDetail而言,一个Job可以对应多个Trigger

创建Scheduler的方式有两种:

方式一:

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

方式二:

SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();

2.2、Quartz.properties

默认路径:quartz.2.3.0中的org.quartz中的quartz.properties

在这里插入图片描述

组成部分:

  • 调度器属性

org.quartz.scheduler.instanceName:属性用来区分特定的调度器实例,可以按照功能用途来给调度器起名。

org.quartz.scheduler.instanceId:属性和前者一样,允许任何字符串,但是这个值必须要在所有的调度器实例中是唯一的,尤其是在一个集群的环境中。作为唯一的key。

  • 线程池属性

threadCount

处理Job的线程数目,至少为1,但是最多的话最好不要超过100,再多台机器上设置值超过100的话,会显得相当不适用。特别是在Job执行时间较长的情况下。

  • threadPriority

现成的优先级,优先级高的线程优先得到执行。最小的1;其次最大的是10。默认是5


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

相关文章

Quartz定时任务

Java实现定时任务的方式 一、线程等待&#xff08;不建议使用&#xff0c;任务复杂时存在内存泄露风险&#xff09; Thread myThread new Thread(new Runnable() {Overridepublic void run() {while (true) {System.out.println("TestThreadWait is called!");try…

java定时任务Quartz整理

目录 一、Quartz介绍 二、Quartz的组成 三、使用java实现一个简单的Quartz例子 四、使用Springboot整合Quartz定时任务框架 五、使用Springbootmybatis整合Quartz定时任务框架实现定时向数据库插入一条数据 六、总结 七、参考资料 一、Quartz介绍 quartz是一种基于java…

Quartz之定时任务

一 基础概念 1.什么是Quartz? Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目&#xff0c;完全由Java开发&#xff0c;可以用来执行定时任务&#xff0c;类似于 java.util.Timer。但是相较于Timer&#xff0c; Quartz增加了很多功能&#xff1a;(1).持久性…

定时任务框架Quartz

目录 一、Quartzh介绍 1、Quartz的定义&#xff1a; 2、Quartz完成定时任务的原理&#xff1a; 二、cron表达式 1、cron表达式定义 2、cron表达式规范 三、spring自带调度器 四、Quartz内存版集成基本使用 1、关于Quartz内存版集成的步骤 1、先到启动类中写好集成的步骤 2、…

定时任务:Quartz 详解

定时任务&#xff1a;Quartz 详解 文章目录 定时任务&#xff1a;Quartz 详解1 Quartz是什么&#xff1f;2 Quartz核心组成3 Quartz核心模块理解3.1 用工厂模式理解 Quartz 的设计机制&#xff1a;3.2 用流程图理解 Quartz 的核心模块关系&#xff1a; 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.输出一个矩阵 代码如下&…