Quartz定时任务

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

Java实现定时任务的方式

一、线程等待(不建议使用,任务复杂时存在内存泄露风险)

Thread myThread = new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("TestThreadWait is called!");try {// 使用线程休眠来实现周期执行Thread.sleep(1000 * 3);} catch (InterruptedException e) {e.printStackTrace();}}}
});
myThread.start();

二、Timer

package com.changan.test;import java.util.Timer;
import java.util.TimerTask;public class Main {public static void main(String[] args) {/*Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("执行定时任务");}},1000,1000);*/TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("TimerTask is called!");}};Timer timer = new Timer();/** schedule 和 scheduleAtFixedRate 区别:*  可将schedule理解为scheduleAtFixedDelay,*  两者主要区别在于delay和rate*  1、schedule,如果第一次执行被延时(delay),*      随后的任务执行时间将以上一次任务实际执行完成的时间为准*  2、scheduleAtFixedRate,如果第一次执行被延时(delay),*      随后的任务执行时间将以上一次任务开始执行的时间为准(需考虑同步)**  参数:1、任务体    2、延时时间(可以指定执行日期)3、任务执行间隔时间*/// timer.schedule(task, 0, 1000 * 3);timer.scheduleAtFixedRate(task, 0, 1000 * 3);}
}

三、ScheduledExecutorService

package com.changan.test;import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class Main {public static void main(String[] args) {Runnable runnable = new Runnable() {public void run() {System.out.println("ScheduledExecutorService Task is called!");}};ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();// 参数:1、任务体 2、首次执行的延时时间//      3、任务执行间隔 4、间隔时间单位service.scheduleAtFixedRate(runnable, 0, 3, TimeUnit.SECONDS);}
}

四、@Scheduled

1、配置

在spring boot的启动类上加@EnableScheduling注解,允许支持@Scheduled:

@SpringBootApplication
@EnableScheduling
public class Quartz01Application {public static void main(String[] args) {SpringApplication.run(Quartz01Application.class, args);}
}

2、任务类

@Component
public class ScheduleTask {// 每隔5秒执行一次@Scheduled(cron = "0/5 * * * * ?")public void printSay() {System.out.println("每隔5秒执行一次:" + new Date());}
}

Quartz

一、Quartz介绍

quartz是一种基于java实现的任务调度框架,可以定时自动的执行你想要执行的任何任务。

quartz官网:http://www.quartz-scheduler.org/

二、Quartz的组成

任务Job(你要做什么事?)

job就是你想要实现的任务类,每一个job必须实现org.quartz.job接口。

触发器Trigger(你什么时候去做?)

Trigger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,Trigger将会设置3点进行执行该任务。

调度器Scheduler(你什么时候需要做什么事?)

Scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job。

三、使用java实现一个简单的Quartz例子

1、新建一个maven项目,并引入Quartz依赖 https://mvnrepository.com/search?q=quartz

<dependencies><!--核心包--><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency><!--工具--><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.3.2</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.7</version><scope>compile</scope></dependency>
</dependencies>

2、编写一个Job类,用来编写定时任务要做什么

package com.changan.test.service;import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;import java.text.SimpleDateFormat;
import java.util.Date;public class HelloJob implements Job {public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {//输出当前时间Date date=new Date();SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString=dateFormat.format(date);//工作内容System.out.println("执行定时任务,时间是:"+dateString);}
}

3、编写触发器和调度器

package com.changan.test;import com.changan.test.service.HelloJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;public class HelloSchedulerDemo {public static void main(String[] args) throws Exception{//1、调度器(Schedular),从工厂中获取调度实例(默认:实例化new StdSchedulerFactory();)Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler();//2、任务实例(JobDetail)JobDetail jobDetail= JobBuilder.newJob(HelloJob.class) //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口.withIdentity("job1","group1") //参数1:任务的名称(唯一实例);参数2:任务组的名称.build();//3、触发器(Trigger)Trigger trigger= TriggerBuilder.newTrigger().withIdentity("trigger1","group1") //参数1:触发器的名称(唯一实例);参数2:触发器组的名称.startNow() //马上启动触发器.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)) //每5秒执行一次.build();//让调度器关联任务和触发器,保证按照触发器定义的条件执行任务scheduler.scheduleJob(jobDetail,trigger);//启动scheduler.start();}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G9mmjoBR-1615167541608)(Quartz/1614958615457.png)]

四、使用Springboot整合Quartz定时任务框架

1.pom.xml

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

2、 job类

package com.changan.service;import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;import java.util.Date;public class QuartzDemo implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.out.println("Execute..."+new Date());}
}

3、配置类,配置触发器与任务调度器

package com.changan.config;import com.changan.service.QuartzDemo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;/*** Quartz配置类*/
@Configuration
public class QuartzConfig {/*** 1、创建Job对象*/@Beanpublic JobDetailFactoryBean jobDetailFactoryBean(){JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();//关联我们自己的Job类factoryBean.setJobClass(QuartzDemo.class);return factoryBean;}/*** 2、创建Trigger对象*/@Beanpublic SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){SimpleTriggerFactoryBean factoryBean=new SimpleTriggerFactoryBean();//关联JobDetail对象factoryBean.setJobDetail(jobDetailFactoryBean.getObject());//该参数表示一个执行的毫秒数factoryBean.setRepeatInterval(2000); //每隔2秒执行一次//重复次数factoryBean.setRepeatCount(5);return factoryBean;}/*** 3、创建Scheduler*/@Beanpublic SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();//关联triggerfactoryBean.setTriggers(simpleTriggerFactoryBean.getObject());return factoryBean;}
}

4、启动类

package com.changan;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication
@EnableScheduling
public class Quartz01Application {public static void main(String[] args) {SpringApplication.run(Quartz01Application.class, args);}
}

五、使用Springboot+mybatis整合Quartz定时任务框架实现定时向数据库插入一条数据

QuartzDemo

package com.changan.service;import com.changan.entity.User;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;import java.util.Date;public class QuartzDemo implements Job {@Autowiredprivate UserService userService;@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {User user = new User();user.setEmail("123123");user.setAge(12);user.setName("456");userService.save(user);}
}

因此我们需要手动的把QuartzDemoJob类注入到SpringIOC容器中。

编写一个类MyAdaptableJobFactory继承AdaptableJobFactory,覆盖createJobInstance()方法。

MyadaptableJobFactory

package com.changan.config;import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;@Component("myadaptableJobFactory")  //将该类实例化,使得可以直接用
public class MyadaptableJobFactory extends AdaptableJobFactory {//AutowireCapableBeanFactory可以将一个对象添加到Spring IOC容器中,并且完成该对象注入@Autowiredprivate AutowireCapableBeanFactory autowireCapableBeanFactory;//该方法将实例化的任务对象手动的添加到SpringIOC容器中并且完成对象的注入@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {Object object = super.createJobInstance(bundle);//将object对象添加到Spring IOC容器中并完成注入this.autowireCapableBeanFactory.autowireBean(object);return object;}
}

QuartzConfig

package com.changan.config;import com.changan.service.QuartzDemo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;/*** Quartz配置类*/
@Configuration
public class QuartzConfig {/*** 1、创建Job对象*/@Beanpublic JobDetailFactoryBean jobDetailFactoryBean(){JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();//关联我们自己的Job类factoryBean.setJobClass(QuartzDemo.class);return factoryBean;}/*** 2、创建Trigger对象*/@Beanpublic SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){SimpleTriggerFactoryBean factoryBean=new SimpleTriggerFactoryBean();//关联JobDetail对象factoryBean.setJobDetail(jobDetailFactoryBean.getObject());//该参数表示一个执行的毫秒数factoryBean.setRepeatInterval(2000); //每隔2秒执行一次//重复次数factoryBean.setRepeatCount(5);return factoryBean;}/*** 3、创建Scheduler*/@Beanpublic SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean, MyadaptableJobFactory myadaptableJobFactory){SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();//关联triggerfactoryBean.setTriggers(simpleTriggerFactoryBean.getObject());factoryBean.setJobFactory(myadaptableJobFactory);return factoryBean;}
}

CronExpression表达式

格式:[秒] [分] [时] [每月的第几日] [月] [每周的第几日] [年]

字段名必须的允许值允许的特殊字符
SecondsYES0-59, - * /
MinutesYES0-59, - * /
HoursYES0-23, - * /
Day of monthYES1-31, - * ? / L W
MonthYES1-12 or JAN-DEC, - * /
Day of weekYES1-7 or SUN-SAT, - * ? / L #
YearNOempty, 1970-2099, - * /

特殊字符说明:

字符含义
*用于 指定字段中的所有值。比如:* 在分钟中表示 每一分钟
?用于 指定日期中的某一天,或是 星期中的某一个星期
-用于 指定范围。比如:10-12 在小时中表示 10 点,11 点,12 点
,用于 指定额外的值。比如:MON,WED,FRI 在日期中表示 星期一, 星期三, 星期五
/用于 指定增量。比如:0/15 在秒中表示 0 秒, 15 秒, 30 秒, 45 秒5/15 在秒中表示 5 秒,20 秒,35 秒,50 秒
L在两个字段中拥有不同的含义。比如:L 在日期(Day of month)表示 某月的最后一天。在星期(Day of week)只表示 7SAT。但是,值L 在星期(Day of week)中表示 某月的最后一个星期几。比如:6L 表示 某月的最后一个星期五。也可以在日期(Day of month)中指定一个偏移量(从该月的最后一天开始).比如:L-3 表示 某月的倒数第三天
W用于指定工作日(星期一到星期五)比如:15W 在日期中表示 到 15 号的最近一个工作日。如果第十五号是周六, 那么触发器的触发在 第十四号星期五。如果第十五号是星期日,触发器的触发在 第十六号周一。如果第十五是星期二,那么它就会工作开始在 第十五号周二。然而,如果指定 1W 并且第一号是星期六,那么触发器的触发在第三号周一,因为它不会 “jump” 过一个月的日子的边界。
LW可以在日期(day-of-month)合使用,表示 月份的最后一个工作日
#用于 指定月份中的第几天。比如:6#3 表示 月份的第三个星期五(day 6 = Friday and “#3” = the 3rd one in the month)。其它的有,``2#1表示月份第一个星期一4#5表示月份第五个星期三。注意: 如果只是指定#5,则触发器在月份中**不会**触发。

注意:字符不区分大小写,MONmon 相同。

cronExpression 示例

表达式含义
0 0 12 * * ?每天中午 12 点
0 15 10 ? * *每天上午 10 点 15 分
0 15 10 * * ?每天上午 10 点 15 分
0 15 10 * * ? *每天上午 10 点 15 分
0 15 10 * * ? 2005在 2005 年里的每天上午 10 点 15 分
0 * 14 * * ?每天下午 2 点到下午 2 点 59 分的每一分钟
0 0/5 14 * * ?每天下午 2 点到 2 点 55 分每隔 5 分钟
0 0/5 14,18 * * ?每天下午 2 点到 2 点 55 分, 下午 6 点到 6 点 55 分, 每隔 5 分钟
0 0-5 14 * * ?每天下午 2 点到 2 点 5 分的每一分钟
0 10,44 14 ? 3 WED3 月每周三的下午 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 L-2 * ?每月最后两天的上午10点15分
0 15 10 ? * 6L每月的最后一个星期五的上午 10 点 15 分
0 15 10 ? * 6L 2002-20052002 年到 2005 年每个月的最后一个星期五的上午 10 点 15 分
0 15 10 ? * 6#3每月的第三个星期五的上午 10 点 15 分
0 0 12 1/5 * ?每月的 1 号开始每隔 5 天的中午 12 点
0 11 11 11 11 ?每年 11 月 11 号上午 11 点 11 分

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

相关文章

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.输出一个矩阵 代码如下&…

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. 什么是嵌套 嵌套是指一个对象中包含另一个与它相似的对象…