Quartz是一个非常强大的定时任务调度工具,笔者就职的公司大数据部门专门以Quartz为基础开发出一套定时调度系统。可见Quartz功能的强大,实际工作中,大多数开发者都会使用Quartz来完成定时任务,而非Timer。
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
Quartz主要用到的设计模式:
Builder模式
Factory模式
组件模式
链式写法
三个核心概念
调度器、任务、触发器
Quartz的体系结构
scheduler、JobDetail、trigger(SimpleTrigger/CronTrigger)
重要组成
Job、JobDetail、JobBuilder、JobStore、Trigger、TriggerBuilder、ThreadPool、Scheduler、Calendar、监听器(JobListener、TriggerListener、SchedulerListener)
以下是一个简单的demo:
Job:
package quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:36
**/
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
//编写具体的业务逻辑
System.out.println("Hello World");
}
}
Scheduler:
package quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail=JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","group1").build();
//创建一个Trigger实例,定义该Job立即执行,并且每隔两秒中重复执行一次,直到永远
Trigger trigger=TriggerBuilder
.newTrigger()
.withIdentity("myTrigger","group1")
.startNow()
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
.build();
//创建Scheduler实例
SchedulerFactory sfact=new StdSchedulerFactory();
Scheduler scheduler=sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
scheduler.scheduleJob(jobDetail,trigger);
}
}
浅谈Job和JobDetail
Job的定义:实现业务逻辑的任务接口 Job接口非常容易实现,只有一个execute方法,类似于TimerTask中的run方法,在里面编写业务逻辑
Job实例在Quartz中的生命周期 每次调度器执行Job时,会在调用execute方法前创建一个新的Job实例。当调用完成后,关联的Job对象实例会被释放,释放的实例会被垃圾回收机制回收
JobDetail为Job实例提供很多设置属性,以及JobDataMap成员变量属性,它用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例
JobDetail的重要属性 name(必须)、group(必须,默认default)、jobClass(必须)、jobDataMap
package quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail=JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob").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());
//创建一个Trigger实例,定义该Job立即执行,并且每隔两秒中重复执行一次,直到永远
Trigger trigger=TriggerBuilder
.newTrigger()
.withIdentity("myTrigger","group1")
.startNow()
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
.build();
//创建Scheduler实例
SchedulerFactory sfact=new StdSchedulerFactory();
Scheduler scheduler=sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
scheduler.scheduleJob(jobDetail,trigger);
}
}
浅谈JobExecutionContext
当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute() 方法;Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据
浅谈JobDataMap
在进行任务调度时,JobDataMap存储在JobExecutionContext中,非常方便获取
JobDataMap可以用来装载任何可序列化的数据对象,当Job实例对象被执行时这些参数对象会传递给它
JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型
获取JobDataMap的两种方式
1、直接从Map中获取
Job:
package quartz;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:36
**/
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
JobKey key=context.getJobDetail().getKey();
System.out.println("My Job name and group are: "+key.getName()+":"+key.getGroup());
TriggerKey trkey=context.getTrigger().getKey();
System.out.println("My Trigger name and group are: "+trkey.getName()+":"+trkey.getGroup());
JobDataMap dataMap=context.getJobDetail().getJobDataMap();
JobDataMap tdateMap=context.getTrigger().getJobDataMap();
String jobMsg=dataMap.getString("message");
float jobFloatValue=dataMap.getFloat("FloatJobValue");
String triggerMsg=tdateMap.getString("message");
Double triggerDoubleValue=tdateMap.getDouble("DoubleTriggerValue");
System.out.println("JobMsg is: "+jobMsg);
System.out.println("jobFloatValue is: "+jobFloatValue);
System.out.println("triggerMsg is: "+triggerMsg);
System.out.println("triggerDoubleValue is: "+triggerDoubleValue);
}
}
Scheduler:
package quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail=JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob")
.usingJobData("message","hello myJob1")
.usingJobData("FloatJobValue",3.14F)
.build();
//创建一个Trigger实例,定义该Job立即执行,并且每隔两秒中重复执行一次,直到永远
Trigger trigger=TriggerBuilder
.newTrigger()
.withIdentity("myTrigger","group1")
.usingJobData("message","hello myTrigger1")
.usingJobData("DoubleTriggerValue",2.0D)
.startNow()
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
.build();
//创建Scheduler实例
SchedulerFactory sfact=new StdSchedulerFactory();
Scheduler scheduler=sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
scheduler.scheduleJob(jobDetail,trigger);
}
}
2.Job实现类中添加setter方法对应JobDataMap的键值(Quartz框架默认的JobFactory实现类在初始化Job实例对象时会自动调用这些setter方法)
Job:
package quartz;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:36
**/
public class HelloJob implements Job {
private String message;
private Float FloatJobValue;
private Double DoubleTriggerValue;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Float getFloatJobValue() {
return FloatJobValue;
}
public void setFloatJobValue(Float floatJobValue) {
FloatJobValue = floatJobValue;
}
public Double getDoubleTriggerValue() {
return DoubleTriggerValue;
}
public void setDoubleTriggerValue(Double doubleTriggerValue) {
DoubleTriggerValue = doubleTriggerValue;
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
JobKey key=context.getJobDetail().getKey();
System.out.println("My Job name and group are: "+key.getName()+":"+key.getGroup());
TriggerKey trkey=context.getTrigger().getKey();
System.out.println("My Trigger name and group are: "+trkey.getName()+":"+trkey.getGroup());
//JobDataMap dataMap=context.getMergedJobDataMap();
System.out.println("jobFloatValue is: "+FloatJobValue);
System.out.println("msg is: "+message);
System.out.println("triggerDoubleValue is: "+DoubleTriggerValue);
}
}
Scheduler:(不变,自动为Job中的同名属性赋值)
package quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail=JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob")
.usingJobData("message","hello myJob1")
.usingJobData("FloatJobValue",3.14F)
.build();
//创建一个Trigger实例,定义该Job立即执行,并且每隔两秒中重复执行一次,直到永远
Trigger trigger=TriggerBuilder
.newTrigger()
.withIdentity("myTrigger","group1")
.usingJobData("message","hello myTrigger1")
.usingJobData("DoubleTriggerValue",2.0D)
.startNow()
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
.build();
//创建Scheduler实例
SchedulerFactory sfact=new StdSchedulerFactory();
Scheduler scheduler=sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
scheduler.scheduleJob(jobDetail,trigger);
}
}
浅谈Trigger
触发器通用属性
JobKey 表示job实例的标识,触发器被触发时,该指定的job实例会执行
StartTime 表示触发器时间表首次被触发的时间,它的值类型是java.util.Date
EndTime 指定触发器不再被触发的时间,它的值类型是java.util.Date
Job:
package quartz;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:36
**/
public class HelloJob implements Job {
private String message;
private Float FloatJobValue;
private Double DoubleTriggerValue;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Float getFloatJobValue() {
return FloatJobValue;
}
public void setFloatJobValue(Float floatJobValue) {
FloatJobValue = floatJobValue;
}
public Double getDoubleTriggerValue() {
return DoubleTriggerValue;
}
public void setDoubleTriggerValue(Double doubleTriggerValue) {
DoubleTriggerValue = doubleTriggerValue;
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
Trigger currentTrigger=context.getTrigger();
System.out.println("Start Time Is: "+sf.format(currentTrigger.getStartTime()));
System.out.println("End Time Is: "+sf.format(currentTrigger.getEndTime()));
JobKey jobKey=currentTrigger.getJobKey();
System.out.println("JobKey info---"+"jobName:"+jobKey.getName()+" jobGroup: "+jobKey.getGroup());
}
}
Scheduler:
package quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is: "+sf.format(date));
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail=JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob")
.build();
//获取距离当前时间3秒后的时间
date.setTime(date.getTime()+3000);
//获取距离当前时间6秒后的时间
Date endDate=new Date();
endDate.setTime(endDate.getTime()+6000);
//创建一个Trigger实例,定义该Job立即执行,并且每隔两秒中重复执行一次,直到永远
Trigger trigger=TriggerBuilder
.newTrigger()
.withIdentity("myTrigger","group1")
.startAt(date)
.endAt(endDate)
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
.build();
//创建Scheduler实例
SchedulerFactory sfact=new StdSchedulerFactory();
Scheduler scheduler=sfact.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail,trigger);
}
}
SimpleTrigger:在一个指定时间段内执行一次作业任务或者在指定的时间间隔内多次执行作业任务
SimpleTrigger举例:
Job:
package quartz;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:36
**/
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is: "+sf.format(date));
System.out.println("Hello World");
}
}
Scheduler:
package quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is: " + sf.format(date));
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob")
.build();
//创建一个Trigger实例
//获取距离当前4秒钟之后的具体时间
date.setTime(date.getTime() + 4000);
//获取距离当前时间6秒钟之后的具体时间
Date endDate=new Date();
endDate.setTime(endDate.getTime()+6000);
//距离当前4秒钟后首次执行任务,之后每隔2秒钟重复执行一次任务,直到距离当前6秒钟为止
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.startAt(date)
.endAt(endDate)
.withSchedule(
SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.withRepeatCount(3)
)
.build();
//创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail, trigger);
}
}
需要注意的点:
重复次数可以为0、正整数或者SimpleTrigger.REPEAT_INDEFINITELY常量值
重复执行间隔必须是0或者长整数
一旦指定了endTime参数,那么他会覆盖重复次数参数的效果
CronTrigger
基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用(每个月5号,或者每个星期一、三运行任务)
Cron表达式:用于配置CronTrigger实例,是由7个子表达式组成的字符串,描述了时间表的详细信息。
格式:[秒] [分] [小时] [日] [月] [周] [年]
各字段的含义
字段 | 允许值 | 允许的特殊字符 |
秒(Seconds) | 0~59的整数 | , - * / 四个字符 |
分(Minutes) | 0~59的整数 | , - * / 四个字符 |
小时(Hours) | 0~23的整数 | , - * / 四个字符 |
日期(DayofMonth) | 1~31的整数(但是你需要考虑你月的天数) | ,- * ? / L W C 八个字符 |
月份(Month) | 1~12的整数或者 JAN-DEC | , - * / 四个字符 |
星期(DayofWeek) | 1~7的整数或者 SUN-SAT (1=SUN) | , - * ? / L C # 八个字符 |
年(可选,留空)(Year) | 1970~2099 | , - * / 四个字符 |
注意事项:
每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:
(1)*:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。
(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。
(3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
(4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.
(5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
(6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。
(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
(9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。
(10)MON月份不区分大小写
(11)百度在线生成器
举例:
0 15 10 ? * * 每天10点15分触发
0 0/5 14 * * ? 每天下午的2点到2点59分(0点开始,每隔5分钟触发)
0 15 10 ? * MON-FRI 从周一到周五每天的上午的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 15 10 ? 6L 2016-2017 从2016年到2017年每月最后一周的星期五的10点15分触发
package quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is: " + sf.format(date));
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob")
.build();
//创建一个Trigger实例,每秒触发一次任务
CronTrigger trigger = (CronTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(
CronScheduleBuilder
.cronSchedule("0 15 10 ? * * 2017")
)
.build();
//1.2017年内每天10点15分触发一次
// 0 15 10 ? * * 2017
//2.每天的14点整至14点59分55秒,以及18点整至18点59分55秒,每5秒钟触发一次
// 0/5 * 14,18 * * ?
//3.每月周一至周五的10点15分触发一次
//4.每月最后一天的10点15分触发一次
//5.每月第三个周五的10点15分触发一次
//创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail, trigger);
}
}
浅谈Scheduler:
Scheduler--工厂模式 所有的Scheduler案例应该由SchedulerFactory来创建
//Scheduler的两种创建方式
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
DirectSchedulerFactory factory=DirectSchedulerFactory.getInstance();
Scheduler scheduler=factory.getScheduler();
StdSchedulerFactory 使用一组参数(java.util.Properties)来创建和初始化Quartz调度器,配置参数一般存在quartz.properties中。调用getScheduler() 方法就能创建和初始化调度对象。
Scheduler的主要函数:
Date scheduleJob(JobDetail jobDetail,Trigger trigger) 返回最近一次的执行时间
void start() 启动
void standby() 暂时挂起
void shutdown() 完全关闭Schedule,无法重启
package quartz;
import org.quartz.*;
import org.quartz.impl.DirectSchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author Rhine
* @Date 2019/1/21 17:42
**/
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException, InterruptedException {
//打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is: " + sf.format(date));
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob")
.build();
//创建一个Trigger实例,每秒触发一次任务
CronTrigger trigger = (CronTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(
CronScheduleBuilder
.cronSchedule("* * * * * ?")
)
.build();
//创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
System.out.println("scheduler time is: "+sf.format(scheduler.scheduleJob(jobDetail, trigger)));
//scheduler执行两秒后挂起
Thread.sleep(2000L);
// scheduler.standby();
scheduler.shutdown();
//shutdown(true)表示等待所有正在执行的job执行完毕后,再关闭scheduler
//shutdown(false)即shutdown()表示直接关闭scheduler
//scheduler挂起三秒后继续执行
Thread.sleep(3000L);
scheduler.start();
}
}
quartz.properties
文档的位置和加载顺序
调度器属性
org.quartz.scheduler.instanceName用来区分特定的调度器实例,可以按照功能用途来给调度器起名
org.quartz.scheduler.instanceId 属性和前者一样,也允许任何字符串,但这个值必须是在所有调度器实例中是唯一的, 尤其是在一个集群中,作为唯一key。假如你想Quartz帮你生成这个值,可以设置为AUTO
线程池属性
threadCount:线程数
threadPriority:优先级
org.quartz.threadPool.class
作业存储属性
描述了在调度器实例中,Job和Trigger信息是如何被存储的
插件属性
满足特定需求用到的Quartz插件的配置
在实际使用中搭配@Component、@Scheduling、@Schedule以及Cron表达式的使用