博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Quartz入门
阅读量:3960 次
发布时间:2019-05-24

本文共 12219 字,大约阅读时间需要 40 分钟。

Quartz简介及应用场景

Quartz介绍

任务调度框架“Quartz”是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
简单来说就是实现“计划(或定时)任务”的系统,例如:订单下单后未付款,15分钟后自动撤消订单,并自动解锁锁定的商品
Quartz的触发器
触发器用来告诉调度程序作业什么时候触发。框架提供了5种触发器类型,但两个最常用的SimpleTrigger 简单触发器CronTrigger 表达式触发器
五种类型的Trigger(定时器)
SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar类( org.quartz.Calendar)。
场景
SimpleTrigger:执行N次,重复N次
CronTrigger:几秒 几分 几时 哪日 哪月 哪周 哪年,执行
存储方式
RAMJobStore(内存作业存储类型)和JDBCJobStore(数据库作业存储类型),
两种方式对比如下:
RAMJobStore
优点: 不要外部数据库,配置容易,运行速度快
缺点:因为调度程序信息是存储在被分配给JVM的内存里面, 所以,当应用程序停止运行时,所有调度信息将被丢失。 另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制
JDBCJobStor
优点:支持集群,因为所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务
缺点:运行速度的快慢取决与连接数据库的快慢
图解quartz工作流程
在这里插入图片描述
核心类和核心类之间关系
QuartzSchedulerThread:负责执行向QuartzScheduler注册的触发Trigger的工作的线程。
ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提供运行效率。
QuartzSchedulerResources:包含创建QuartzScheduler实例所需的所有资源(JobStore,ThreadPool等)。
SchedulerFactory:提供用于获取调度程序实例的客户端可用句柄的机制。
JobStore:通过类实现的接口,这些类要为org.quartz.core.QuartzScheduler的使用提供一个org.quartz.Job和org.quartz.Trigger存储机制。 作业和触发器的存储应该以其名称和组的组合为唯一性。
QuartzScheduler:这是Quartz的核心,它是org.quartz.Scheduler接口的间接实现,包含调度org.quartz.Jobs,注册org.quartz.JobListener实例等的方法。
Scheduler:这是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。 一旦注册,调度程序负责执行作业,当他们的相关联的触发器触发(当他们的预定时间到达时)。
Trigger:具有所有触发器通用属性的基本接口,描述了job执行的时间出发规则。 - 使用TriggerBuilder实例化实际触发器。
JobDetail:传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。
1.jobname+jobgroup=primary key identity
2.jobdetail每执行一次都会新建一个job实例
Job:示要执行的“作业”的类实现的接口。只有一个方法 void execute(jobExecutionContext context)
(jobExecutionContext 提供调度上下文各种信息,运行时数据保存在jobDataMap中)
Job有个子接口StatefulJob ,代表有状态任务。
有状态任务不可并发,前次任务没有执行完,后面任务处于阻塞等待
jobName+groupName=primary key

注1:这里面最最重要的接口是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。   翻译:Scheduler的中文是:“调度程序,日程安排程序”

quartz相关表达式

在这里插入图片描述
在这里插入图片描述

Quartz简单触发器

SimpleTrigger介绍

每次执行 * 长时间,每次间隔 * 长时间
案例需要的功能
在这里插入图片描述
所需pom依赖

org.springframework
spring-aspects
org.quartz-scheduler
quartz
2.2.1
org.quartz-scheduler
quartz-jobs
2.2.1

创建自定义RamJob

package com.zxp.quartz01.job;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-03 20:43 * * 创建自定义RamJob * 必须实现org.quartz.Job接口 * */public class RamJob implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        System.err.println("这里就是定时任务启动会执行的代码块");    }}

测试类

package com.zxp.quartz01.demo;import com.zxp.quartz01.job.RamJob;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import static org.quartz.JobBuilder.newJob;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-03 20:39 *Quartz简单触发器  * quartz的入门级案例 * 讲解quartz定时任务调用过程(基于内存) * schedulefactory、schedule、Trigger、jobdetail */public class Demo1 {    public static void main(String[] args) throws Exception {//        SchedulerFactory 提供用于获取调度程序实例的客户端可用句柄的机制。        SchedulerFactory schedulerFactory=new StdSchedulerFactory();//        Scheduler  这是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。        Scheduler scheduler= schedulerFactory.getScheduler();//        JobDetail 传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。        JobDetail jobDetail=newJob(RamJob.class)//               组成唯一标识                .withIdentity("job1","group1")                .withDescription("这是第一个定时任务案例")                .build();//构建触发器(存放定时任务执行规则) 使用TriggerBuilder实例化实际触发器。        Trigger trigger=(Trigger) TriggerBuilder.newTrigger()//                定时任务每六秒执行一次一共执行三次                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3,6))                .withIdentity("trigger1","group1")                .withDescription("这是第一个触发器")                .build();//       调度工厂绑定作业类及触发器        scheduler.scheduleJob(jobDetail,trigger);//        启动定时任务        scheduler.start();    }}

在这里插入图片描述

Quartz表达式触发器

CronTirgger介绍

测试类

package com.zxp.quartz01.demo;import com.zxp.quartz01.job.RamJob;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import static org.quartz.JobBuilder.newJob;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-03 20:39 * * quartz的入门级案例 * 讲解quartz定时任务调用过程(基于内存) * schedulefactory、schedule、Trigger、jobdetail * Quartz表达式触发器 * 表达式触发器比简单触发器灵活 * */public class Demo2 {    public static void main(String[] args) throws Exception {//        SchedulerFactory 提供用于获取调度程序实例的客户端可用句柄的机制。        SchedulerFactory schedulerFactory=new StdSchedulerFactory();//        Scheduler  这是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。        Scheduler scheduler= schedulerFactory.getScheduler();//        JobDetail 传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。        JobDetail jobDetail=newJob(RamJob.class)//               组成唯一标识                .withIdentity("job2","group1")                .withDescription("这是第二个定时任务案例")                .build();//构建触发器(存放定时任务执行规则) 使用TriggerBuilder实例化实际触发器。        Trigger trigger=(Trigger) TriggerBuilder.newTrigger()//                指定表达触发器规则 CronTirgger    ("5/3 * * * * ?"))从第五秒开始每三秒执行一次,无上限//                .withSchedule(CronScheduleBuilder.cronSchedule(" 5/3 * * * * ?"))//                定时定点执行                .withSchedule(CronScheduleBuilder.cronSchedule("0 23 21 * * ?"))                .withIdentity("trigger2","group1")                .withDescription("这是第一个触发器")                .build();//       调度工厂绑定作业类及触发器        scheduler.scheduleJob(jobDetail,trigger);//        启动定时任务        scheduler.start();    }}

测试(“5/3 * * * * ?”))从第五秒开始每三秒执行一次,无上限

在这里插入图片描述
测试(“0 23 21 * * ?”)) 定时定点执行
在这里插入图片描述

Quartz中参数传递

package com.zxp.quartz01.demo;import com.zxp.quartz01.job.RamJob;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import static org.quartz.JobBuilder.newJob;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-04 10:24 */public class Demo3 {    public static void main(String[] args) throws SchedulerException {        SchedulerFactory factory = new StdSchedulerFactory();//        调度器创建        Scheduler scheduler = factory.getScheduler();//        具体定时任务需要执行的代码        JobDetail jobDetail = newJob(RamJob.class)                .withIdentity("job2", "group1")                .withIdentity("这是一个作业类案例")                .build();        JobDataMap jobDataMap = jobDetail.getJobDataMap();        jobDataMap.put("name","學習");        jobDataMap.put("level","初級级");        jobDataMap.put("job","软件开发");        Trigger trigger = (Trigger) TriggerBuilder.newTrigger()//                每6s执行一次                .withSchedule(CronScheduleBuilder.cronSchedule("0/6 * * * * ?"))//                定时定点执行//                .withSchedule(CronScheduleBuilder.cronSchedule("0 52 09 * * ?"))//                触发器标识                .withIdentity("trigger2", "group1")                .withDescription("这是一个触发器")                .build();//       调度工厂绑定作业类及触发器        scheduler.scheduleJob(jobDetail, trigger);        scheduler.start();    }}
package com.zxp.quartz01.job;import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-03 20:43 * * 创建自定义RamJob * 必须实现org.quartz.Job接口 * */public class RamJob implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {//        System.err.println("这里就是定时任务启动会执行的代码块");//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//        System.err.println(format.format(new Date())+" : 这是一个Quartz...");////        try {//            Thread.sleep(20*1000);//            System.out.println("模拟正在处理大数据....");//        } catch (InterruptedException e) {//            e.printStackTrace();//        }        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();        System.out.println(jobDataMap.get("name").toString() + jobDataMap.get("level").toString() + jobDataMap.get("job"));    }}

測試

在这里插入图片描述
Spring task Vs Quartz
Spring task
优点:无需整合spring,作业类中就可以调用业务service
缺点:单线程;不能做数据存储型的定时任务
Quartz
优点:多线程;可以做数据存储型的定时任务,维护性高;
缺点:需要整合spring,不能直接调用业务层service;
演示Spring task缺点

package com.zxp.quartz01.task;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Service;import java.text.SimpleDateFormat;import java.util.Date;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-03 21:29 */@Servicepublic class SpringTask {    @Scheduled(cron = "0/10 * * * * ?")    public void xxx(){        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        System.err.println(format.format(new Date())+" : 这是一个spring task...");        try {            Thread.sleep(20*1000);            System.out.println("模拟正在处理大数据....");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

测试类

package com.zxp.quartz01;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableScheduling;//spring task注解@EnableScheduling@SpringBootApplicationpublic class Quartz01Application {    public static void main(String[] args) {        SpringApplication.run(Quartz01Application.class, args);    }}

结果是spring task中的定时任务变成了30s执行一次

在这里插入图片描述
演示Quartz代码

package com.zxp.quartz01.demo;import com.zxp.quartz01.job.RamJob;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import static org.quartz.JobBuilder.newJob;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-03 20:39 * * quartz的入门级案例 * 讲解quartz定时任务调用过程(基于内存) * schedulefactory、schedule、Trigger、jobdetail * Quartz表达式触发器 * 表达式触发器比简单触发器灵活 * */public class Demo2 {    public static void main(String[] args) throws Exception {//        SchedulerFactory 提供用于获取调度程序实例的客户端可用句柄的机制。        SchedulerFactory schedulerFactory=new StdSchedulerFactory();//        Scheduler  这是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。        Scheduler scheduler= schedulerFactory.getScheduler();//        JobDetail 传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。        JobDetail jobDetail=newJob(RamJob.class)//               组成唯一标识                .withIdentity("job2","group1")                .withDescription("这是第二个定时任务案例")                .build();//构建触发器(存放定时任务执行规则) 使用TriggerBuilder实例化实际触发器。        Trigger trigger=(Trigger) TriggerBuilder.newTrigger()//                指定表达触发器规则 CronTirgger    ("5/3 * * * * ?"))从第五秒开始每三秒执行一次,无上限//                .withSchedule(CronScheduleBuilder.cronSchedule(" 5/3 * * * * ?"))//                定时定点执行//                .withSchedule(CronScheduleBuilder.cronSchedule("0 23 21 * * ?"))                .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))                .withIdentity("trigger2","group1")                .withDescription("这是第一个触发器")                .build();//       调度工厂绑定作业类及触发器        scheduler.scheduleJob(jobDetail,trigger);//        启动定时任务        scheduler.start();    }}

RamJob

package com.zxp.quartz01.job;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import java.text.SimpleDateFormat;import java.util.Date;/** * @author笑笑 * @site www.xiaoxiao.com * @company * @create 2020-01-03 20:43 * * 创建自定义RamJob * 必须实现org.quartz.Job接口 * */public class RamJob implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {//        System.err.println("这里就是定时任务启动会执行的代码块");        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        System.err.println(format.format(new Date())+" : 这是一个Quartz...");        try {            Thread.sleep(20*1000);            System.out.println("模拟正在处理大数据....");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

结果:不管前一个定时任务的线程是否结束,都会开启下一个线程,依然每10s执行一次;

在这里插入图片描述

转载地址:http://hurzi.baihongyu.com/

你可能感兴趣的文章
hdu——1711Number Sequence(kmp专练)
查看>>
strstr函数和find函数的异同
查看>>
Java的反射
查看>>
HTTP请求之POST与GET区别
查看>>
SSM结合Redis
查看>>
优化数据库的八种方法
查看>>
Java Web服务收到请求时线程的情况以及session情况
查看>>
SSM配置文件信息加密实现
查看>>
@Produces注解
查看>>
谈谈序列化—实体bean一定要实现Serializable接口?
查看>>
实用小技巧之电脑如何滚动截屏/截取长图
查看>>
Eclipse离线安装Java Decompiler插件
查看>>
Http预请求options
查看>>
未来设计师的工作模式?从室内设计领域的实时设计说起 | Mixlab趋势
查看>>
智能设计 | MixAI 知识库 No.69
查看>>
通过研究微信文章的相关推荐逻辑 ,尝试生成指南| Mixlab设计黑客
查看>>
这个世界上肯定有另一个我,做着我不敢做的事,过着我想过的生活 | MixAI 知识库 No.70...
查看>>
表情包数据挖掘 | Mix群聊
查看>>
如何阅读科研论文
查看>>
理解本真的REST架构风格
查看>>