1. 介绍
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源的任务调度框架,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。
官网:http://www.quartz-scheduler.org/
2.特点
强大的调度功能,spring默认的任务调度框架。
灵活的应用方式
分布式和集群能力
3.用到的主要设计模式
Builder模式 组件模式
Factory模式 链式写法
4.体系结构:
1.三个核心概念:
调度器 任务 触发器
2.体系结构:
JobDetail
trigger
SimpleTrigger
CronTrigger
scheduler
start
stop
pause
resume
示例图:
3.定时器种类
Quartz 中五种类型的 Trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar 类( org.quartz.Calendar)。
最常用的:
SimpleTrigger:用来触发只需执行一次或者在给定时间触发并且重复N次且每次执行延迟一定时间的任务。
CronTrigger:按照日历触发,例如“每个周五”,每个月10日中午或者10:15分。
核心类
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创建/定义。
Job:要由表示要执行的“作业”的类实现的接口。只有一个方法 void execute(jobExecutionContext context)
(jobExecutionContext 提供调度上下文各种信息,运行时数据保存在jobDataMap中)
Job有个子接口StatefulJob ,代表有状态任务。
有状态任务不可并发,前次任务没有执行完,后面任务处于阻塞等到。
quartz入门
1.maven配置:
<!--quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.1.7</version> </dependency>
2.编写程序(实现每两秒打印当前日期并且不停的打印)
- 实现job类(HelloJob.java)
package cn.qlq.quartz; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.quartz.TriggerKey; public class HelloJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException { //打印当前的时间 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); System.out.println("current time is:"+sf.format(date)); System.out.println("hello world"); // 编写具体的业务逻辑 } }
- HelloScheduler .java开启任务调度
package cn.qlq.quartz; import static org.quartz.DateBuilder.newDate; import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.TriggerBuilder.newTrigger; import java.util.GregorianCalendar; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.calendar.AnnualCalendar; public class HelloScheduler { public static void main(String[] args) { try { //1. 创建一个JodDetail实例 将该实例与Hello job class绑定 (链式写法XX.XX.XX) JobDetail jobDetail = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在 .withIdentity("myJob","group1") // 定义name/group .build();//2. 定义一个Trigger,定义该job立即执行,并且每两秒钟执行一次,直到永远 Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "group1")// 定义名字和组 .startNow()//现在开始 .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()) .build(); //3. 创建scheduler Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); //4. 将trigger和jobdetail加入这个调度 scheduler.scheduleJob(jobDetail, trigger); //5. 启动scheduler scheduler.start(); } catch (Exception e) { e.printStackTrace(); } } }
注意:创建Scheduler的方式也可以改为:
// 3. 创建scheduler SchedulerFactory sfact = new StdSchedulerFactory(); Scheduler scheduler = sfact.getScheduler();
浅谈job&jobDetail
1.job简介
Job:接口非常容易实现,只有一个execute方法,类似于Timer的run方法,在里面编写业务逻辑。
job实例在quartz中的声明周期:
每次调度器在执行job时,它在执行execute方法前创建一个job实例
当调用完成之后,关联的job对象实例会被释放,释放的实例被垃圾回收期你回收。
2. jobDetail简介
JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定job实例的状态信息系,调度器需要借助Jobdetail对象来添加Job实例。
重要属性:
name:任务的名称,必须属性
group:任务所在的组,也是必须,默认值是DEFAULT,必须的
jobclass:任务的实现类,必须的
jobdatamap:用于传递传参数
例如:将入门代码改造获取jobDetail的属性
package cn.qlq.quartz; import static org.quartz.DateBuilder.newDate; import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.TriggerBuilder.newTrigger; import java.util.GregorianCalendar; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.calendar.AnnualCalendar; public class HelloScheduler { public static void main(String[] args) { try { //1. 创建一个JodDetail实例 将该实例与Hello job class绑定 (链式写法) JobDetail jobDetail = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在 .withIdentity("myJob") // 定义name,默认组是DEFAULT .build(); System.out.println("jobDetail's name:"+jobDetail.getKey().getName()); System.out.println("jobDetail's group:"+jobDetail.getKey().getGroup()); System.out.println("jobDetail's jobClass:"+jobDetail.getJobClass().getName()); //2. 定义一个Trigger,定义该job立即执行,并且每两秒钟执行一次,直到永远 Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "group1")// 定义名字和组 .startNow()//现在开始 .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()) .build(); //3. 创建scheduler Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); //4. 将trigger和jobdetail加入这个调度 scheduler.scheduleJob(jobDetail, trigger); //5. 启动scheduler scheduler.start(); } catch (Exception e) { e.printStackTrace(); } } }