学习Quartz任务调度(一)--Quartz1.8.6框架介绍及简单应用
由于2.0版本以后,2.0版本一下的创建方法将不在适用于2.0版本。
什么是任务调度
根据设定的时间,执行特定的任务
Quartz工作原理
(1)核心概念
Quartz核心概念主要分为3个:
1、任务(Job)
2、触发器(Trigger)
3、调度器(Scheduler)
(2)具体工作原理
在Quartz核心概念中,任务(Job)主要描述需要执行的具体工作,触发器(Trigger)指的是在特定的时间触发任务的执行,调度器(Scheduler)则是任务的实际执行者,负责粘合任务和触发器,达到任务调度的效果。
Quartz环境初始化
Maven依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>1.8.6</version>
</dependency>
Quartz核心概念介绍
任务(Job)
任务:需要执行的具体工作。定义的指定执行的具体工作的java类需要实现quartz的Job接口。
public class MyJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// 执行具体任务
System.out.println("MyJob is Running ..." + "JobDetailName:" + jobExecutionContext.getJobDetail().getName());
}
}
其中,在Job接口中只有一个execute() 方法,在实现类中实现该方法以执行具体任务。通过参数JobExecutionContext可以获取调度上下文的各种信息,如:任务名称等
触发器(Trigger)
触发器:在特定的时间触发任务的执行。SimpleTrigger及 CronTrigger时Trigger子类中最常用的两个触发器。
(1)SimpleTrigger
SimpleTrigger触发器,当且仅需触发一次或者以固定时间间隔周期触发执行;它适合的任务类似于:9:00 开始,每隔1小时,执行一次的场景。
SimpleTrigger的常用构造方法
构造方法 | 参数说明 | 备注 |
---|---|---|
SimpleTrigger(String name, String group) | name:触发器名称 group:触发器所属组 | 调用此构造函数实际是调用了this(name, group, new Date(), (Date)null, 0, 0L),其中默认指定开始时间为当前时间,结束时间为null,repeatCount = 0,repeatInterval = 0L,即当前时间立即执行且只执行一次 |
SimpleTrigger(String name, String group, Date startTime) | name:触发器名称 group:触发器所属组 startTime:开始时间 | 调用此构造函数实际是调用了this(name, group, startTime, (Date)null, 0, 0L);,其中默认指定结束时间为null,repeatCount = 0,repeatInterval = 0L,即设定开始时间立即执行且只执行一次 |
SimpleTrigger(String name, String group, Date startTime, Date endTime, int repeatCount, long repeatInterval) | name:触发器名称 group:触发器所属组 startTime:开始时间 endTime:结束时间 repeatCount:重复执行次数 repeatInterval:时间间隔 | 这里需注意的是repeatCount指定不同值的时候使用不同处理策略,详细见下文 |
REPEAT_INDEFINITELY用于指定执行次数,默认值为-1,意思为重复无限次,直到触发器的结束时间戳.如果没有设置结束时间那么将会一直执行下去。详细见测试1
测试通用MyJob.java
package cn.quartz.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyJob implements Job {
private static Integer count = 0;
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
count++;
// 执行具体任务
System.out.println("MyJob is Running ..." + "执行第:" + count + "次" + " Date:" + sdf.format(new Date()));
}
}
测试1:REPEAT_INDEFINITELY
(1)REPEAT_INDEFINITELY,如果未指定结束时间,那么启动后将一直执行下去。
public static void main(String[] args) throws Exception{
JobDetail job = new JobDetail("jobName", "jobGroup", MyJob.class);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
Long currentTimeMillis = System.currentTimeMillis();
SimpleTrigger simTrig = new SimpleTrigger("simTrigName","simTrigGroup");
simTrig.setStartTime(new Date(currentTimeMillis));
simTrig.setEndTime(null);
simTrig.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
simTrig.setRepeatInterval(1000);
//simTrig.setMisfireInstruction(SimpleTrigger.REPEAT_INDEFINITELY);
SchedulerFactory sfc = new StdSchedulerFactory();
System.out.println("设置开始时间:" + sdf.format(new Date(currentTimeMillis)));
System.out.println("实际开始时间:" + sdf.format(new Date()));
Scheduler sched = sfc.getScheduler();
sched.scheduleJob(job,simTrig);
sched.start();
}
测试结果:
(2)REPEAT_INDEFINITELY,如果指定了结束时间,那么启动后将在结束时间后停止执行。
(2) CronTrigger
CronTrigger通常适用于指定时间点的调度任务(例如:每天凌晨1:00 执行1 次)。
Cron表达式:用于描述指定时间点,例如每天每天凌晨1:00执行。 Cron表达式由6~7个由空格分隔的时间元素组成,第7个元素可选。
位置 | 字段含义 | 范围 | 允许的特殊字符 |
---|---|---|---|
1 | 秒 | 0~59 | * / |
2 | 分钟 | 0~59 | * / |
3 | 小时 | 0~23 | * / |
4 | 月份中的哪一天 | 1~31 | * / ? L |
5 | 月份 | 1~12 或 JAN~DEC | * / |
6 | 星期几 | 1~7 或 SUN~SAT(1表示星期天) | * / ? L # |
7 | 年份 | 1970~2099 | * / |
Cron表达式的每个字段,都可以显式地规定一个值(如49)、一个范围(如1-6)、一个列表(如1,3,5)或者一个通配符(如*)。
Cron表达式有几个特殊的字符,说明如下:
1、“ * ”:表示每一个值,它可以用于所有字段
2、“ ? ”:该字符仅用于“月份中的哪一天”字段和“星期几”字段,表示不指定值
3、“ - ”:中划线,表示一个范围
4、“ , ”:使用逗号间隔的数据,表示一个列表
5、“ / ”:通常表示为x/y,x为起始值,y表示值的增量
6、“L”:通常表示为最后。"last"的意思。"L" 用在day-of-month字段意思是 "这个月最后一天";用在 day-of-week字段, 它简单意思是 "7" or "SAT"
7、需注意的是在同时未指定月份中的哪一天和星期几的时候,不可同时使用*或者?代替,必须一个使用*,另一个使用?,否则表达式将会报错。
Cron表达式示例:
0 15 4 * * ? 每天凌晨4 点15
30 0 0 1 1 ? 2014 2014 年1 月1 日凌晨过30执行一次
0 0 14 1,10,20 * ? * 每月的1 号、10 号、20 号的下午2 点
0 0/5 15,17 * * ? 每天15 点到16 点,17 点到18 每5 分钟运行一次
测试:定时每天15:41:00--15:42:00执行,开始时间为15:41:00,且每10s执行一次
public static void main(String[] args) throws Exception{
JobDetail job = new JobDetail("jobName", "jobGroup", MyJob.class);
CronTrigger cronTrigger=new CronTrigger("myTrigger","group","0/10 41 15 ? * * ");
SchedulerFactory sfc = new StdSchedulerFactory();
Scheduler sched = sfc.getScheduler();
sched.scheduleJob(job,cronTrigger);
sched.start();
}
测试结果:
调度器(Scheduler)
调度器:任务的实际执行者,负责粘合任务和触发器。
调度器的具体使用步骤:
通过JobDetail创建一个任务实例
JobDetail job = new JobDetail("jobName", "jobGroup", MyJob.class);
使用SimpleTrigger创建一个触发器
SimpleTrigger simTrig = new SimpleTrigger("simTrigName","simTrigGroup", SimpleTrigger.REPEAT_INDEFINITELY, 3000);
simTrig.setStartTime(new Date(System.currentTimeMillis() + 1000));
创建一个调度器
SchedulerFactory sfc = new StdSchedulerFactory();
Scheduler sched = sfc.getScheduler();
注册任务和触发器
sched.scheduleJob(job, simTrig);
启动和关闭调度
sched.start();
sched.shutdown();