Example1 第一个quartz示例
public class HelloJob implements Job {
private static Logger _log = LoggerFactory.getLogger(HelloJob.class);
public HelloJob() {
}
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
_log.info("Hello World! - " + new Date());
}
}
public class SimpleExample {
public void run() throws Exception {
Logger log = LoggerFactory.getLogger(SimpleExample.class);
log.info("------- Initializing ----------------------");
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
log.info("------- Initialization Complete -----------");
// 下一个整分钟
Date runTime = DateBuilder.evenMinuteDate(new Date());
log.info("------- Scheduling Job -------------------");
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group").build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(runTime).build();
sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + runTime);
sched.start();
log.info("------- Started Scheduler -----------------");
log.info("------- Waiting 65 seconds... -------------");
try {
Thread.sleep(65L * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("------- Shutting Down ---------------------");
sched.shutdown(true);
log.info("------- Shutdown Complete -----------------");
}
public static void main(String[] args) throws Exception {
SimpleExample example = new SimpleExample();
example.run();
}
}
Example2 简单触发器
public class SimpleJob implements Job {
private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);
public SimpleJob() {
}
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
JobKey jobKey = context.getJobDetail().getKey();
_log.info("SimpleJob says: " + jobKey + " executing at " + new Date());
}
}
public class SimpleTriggerExample {
public void run() throws Exception {
Logger log = LoggerFactory.getLogger(SimpleTriggerExample.class);
log.info("------- Initializing -------------------");
// 得到调度器实例的引用
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
log.info("------- Initialization Complete --------");
log.info("------- Scheduling Jobs ----------------");
// jobs can be scheduled before sched.start() has been called
// 任务开始时间的秒数是15的倍数
Date startTime = DateBuilder.nextGivenSecondDate(null, 15);
// job1开始时间的秒数是15的倍数
JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity("job1", "group1").build();
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1").startAt(startTime).build();
// 调度任务
Date ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// job2开始时间的秒数是15的倍数
job = JobBuilder.newJob(SimpleJob.class).withIdentity("job2", "group1").build();
trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(
"trigger2", "group1").startAt(startTime).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// job3开始时间的秒数是15的倍数(运行一次,重复10次,共11次,每次运行间隔为10s)
job = JobBuilder.newJob(SimpleJob.class).withIdentity("job3", "group1").build();
trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger3", "group1").startAt(startTime)
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10).withRepeatCount(10))
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// 相同的job3开始时间的秒数是15的倍数(运行一次,重复2次,共3次,每次运行间隔为10s)
trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger3", "group2").startAt(startTime)
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10).withRepeatCount(2))
.forJob(job).build();
ft = sched.scheduleJob(trigger);
log.info(job.getKey() + " will [also] run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// job4开始时间的秒数是15的倍数(运行一次,重复5次,共6次,每次运行间隔为10s)
job = JobBuilder.newJob(SimpleJob.class).withIdentity("job4", "group1").build();
trigger = TriggerBuilder.newTrigger().withIdentity("trigger4", "group1").startAt(
startTime).withSchedule(
SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).withRepeatCount(5))
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// job5会立即调度,运行时间在5分钟后
job = JobBuilder.newJob(SimpleJob.class).withIdentity("job5", "group1").build();
trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity("trigger5",
"group1").startAt(DateBuilder.futureDate(5, IntervalUnit.MINUTE)).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// job6开始时间的秒数是15的倍数,并且每40秒会重复运行一次,无限重复
job = JobBuilder.newJob(SimpleJob.class).withIdentity("job6", "group1").build();
trigger = TriggerBuilder.newTrigger().withIdentity("trigger6", "group1").startAt(
startTime).withSchedule(
SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(40).repeatForever())
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
log.info("------- Starting Scheduler ----------------");
// 所有的任务已加入调度器,但调度器未开始之前所有的任务都不会运行
sched.start();
log.info("------- Started Scheduler -----------------");
// 调度器运行后任务仍然可以被调度
// job7开始时间的秒数是15的倍数,并且每5分钟会重复运行一次,重复20次
job = JobBuilder.newJob(SimpleJob.class).withIdentity("job7", "group1").build();
trigger = TriggerBuilder.newTrigger().withIdentity("trigger7", "group1").startAt(
startTime).withSchedule(
SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20))
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// job8可以直接运行,而不使用触发器
job = JobBuilder.newJob(SimpleJob.class).withIdentity("job8", "group1")
.storeDurably().build();
sched.addJob(job, true);
log.info("'Manually' triggering job8...");
sched.triggerJob(JobKey.jobKey("job8", "group1"));
log.info("------- Waiting 30 seconds... --------------");
try {
Thread.sleep(30L * 1000L);
} catch (Exception e) {
e.printStackTrace();
}
// job7可以重复调度,开始时间的秒数是15的倍数,并且每5分钟会重复运行一次,重复20次
log.info("------- Rescheduling... --------------------");
trigger = TriggerBuilder.newTrigger().withIdentity("trigger7", "group1").startAt(
startTime).withSchedule(
SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20))
.build();
ft = sched.rescheduleJob(trigger.getKey(), trigger);
log.info("job7 rescheduled to run at: " + ft);
log.info("------- Waiting five minutes... ------------");
try {
// 等待5分钟
Thread.sleep(300L * 1000L);
} catch (Exception e) {
e.printStackTrace();
}
log.info("------- Shutting Down ---------------------");
sched.shutdown(true);
log.info("------- Shutdown Complete -----------------");
// 显示调度器的状态
SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
public static void main(String[] args) throws Exception {
SimpleTriggerExample example = new SimpleTriggerExample();
example.run();
}
}
Example 3 crontab格式的触发器
public class SimpleJob implements Job {
private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);
public SimpleJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
// 打印job的名称和运行时间
JobKey jobKey = context.getJobDetail().getKey();
_log.info("SimpleJob says: " + jobKey + " executing at " + new Date());
}
}
public class CronTriggerExample {
public void run() throws Exception {
Logger log = LoggerFactory.getLogger(CronTriggerExample.class);
log.info("------- Initializing -------------------");
// 得到调度器的引用
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
log.info("------- Initialization Complete --------");
log.info("------- Scheduling Jobs ----------------");
// job可以在调度器运行前被调度
// job 1 每20秒运行1次
JobDetail job = newJob(SimpleJob.class).withIdentity("job1", "group1").build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?"))
.build();
Date ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: "
+ trigger.getCronExpression());
// job 2 在偶数分钟的第15秒运行
job = newJob(SimpleJob.class).withIdentity("job2", "group1").build();
trigger = newTrigger().withIdentity("trigger2", "group1").withSchedule(cronSchedule("15 0/2 * * * ?")).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: "
+ trigger.getCronExpression());
// job 3 在8-17点的偶数分钟运行
job = newJob(SimpleJob.class).withIdentity("job3", "group1").build();
trigger = newTrigger().withIdentity("trigger3", "group1").withSchedule(cronSchedule("0 0/2 8-17 * * ?")).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: "
+ trigger.getCronExpression());
// job 4 在17-23点分钟是3的倍数运行
job = newJob(SimpleJob.class).withIdentity("job4", "group1").build();
trigger = newTrigger().withIdentity("trigger4", "group1").withSchedule(cronSchedule("0 0/3 17-23 * * ?")).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: "
+ trigger.getCronExpression());
// job 5 在每月1号或15号的10点运行
job = newJob(SimpleJob.class).withIdentity("job5", "group1").build();
trigger = newTrigger().withIdentity("trigger5", "group1").withSchedule(cronSchedule("0 0 10am 1,15 * ?")).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: "
+ trigger.getCronExpression());
// job 6 周一至周五的每30秒运行一次
job = newJob(SimpleJob.class).withIdentity("job6", "group1").build();
trigger = newTrigger().withIdentity("trigger6", "group1").withSchedule(cronSchedule("0,30 * * ? * MON-FRI"))
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: "
+ trigger.getCronExpression());
// job 7 在周六、周日的每30秒运行一次
job = newJob(SimpleJob.class).withIdentity("job7", "group1").build();
trigger = newTrigger().withIdentity("trigger7", "group1").withSchedule(cronSchedule("0,30 * * ? * SAT,SUN"))
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: "
+ trigger.getCronExpression());
log.info("------- Starting Scheduler ----------------");
// 调度器运行前所有任务不会运行
sched.start();
log.info("------- Started Scheduler -----------------");
log.info("------- Waiting five minutes... ------------");
try {
Thread.sleep(300L * 1000L);
} catch (Exception e) {
e.printStackTrace();
}
log.info("------- Shutting Down ---------------------");
sched.shutdown(true);
log.info("------- Shutdown Complete -----------------");
SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
public static void main(String[] args) throws Exception {
CronTriggerExample example = new CronTriggerExample();
example.run();
}
}
Example4 向任务传递参数
// 接收参数和维护状态的示例,注意这两个注解
@PersistJobDataAfterExecution // 每次执行后会持久化JobData
@DisallowConcurrentExecution // 不允许并发执行
public class ColorJob implements Job {
private static Logger _log = LoggerFactory.getLogger(ColorJob.class);
// 静态参数
public static final String FAVORITE_COLOR = "favorite color";
public static final String EXECUTION_COUNT = "count";
// 因为quartz每次执行任务时都会重新实例化一个类,所以非静态成员变量不能用来维护状态
private int _counter = 1;
public ColorJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
// 获取jobkey类似group1.job1
JobKey jobKey = context.getJobDetail().getKey();
// 获取并打印传递过来的参数
JobDataMap data = context.getJobDetail().getJobDataMap();
String favoriteColor = data.getString(FAVORITE_COLOR);
int count = data.getInt(EXECUTION_COUNT);
_log.info("ColorJob: " + jobKey + " executing at " + new Date() + "\n" +
" favorite color is " + favoriteColor + "\n" +
" execution count (from job map) is " + count + "\n" +
" execution count (from job member variable) is " + _counter);
// 增加count并保存到job的map中,所以job状态可以维护
count++;
data.put(EXECUTION_COUNT, count);
// 增加本地成员变量,通过成员变量不能维护job状态
_counter++;
}
}
public class JobStateExample {
public void run() throws Exception {
Logger log = LoggerFactory.getLogger(JobStateExample.class);
log.info("------- Initializing -------------------");
// 得到调度器的引用
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
log.info("------- Initialization Complete --------");
log.info("------- Scheduling Jobs ----------------");
// 开始时间秒数是10的倍数
Date startTime = nextGivenSecondDate(null, 10);
// job1 会在秒数是10的倍数开始,重复4次,每10秒重复1次
JobDetail job1 = newJob(ColorJob.class).withIdentity("job1", "group1")
.build();
SimpleTrigger trigger1 = newTrigger()
.withIdentity("trigger1", "group1").startAt(startTime)
.withSchedule(
simpleSchedule().withIntervalInSeconds(10)
.withRepeatCount(4)).build();
// 向 job1 传递参数
job1.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "Green");
job1.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);
Date scheduleTime1 = sched.scheduleJob(job1, trigger1);
log.info(job1.getKey() + " will run at: " + scheduleTime1
+ " and repeat: " + trigger1.getRepeatCount()
+ " times, every " + trigger1.getRepeatInterval() / 1000
+ " seconds");
// job2 会在秒数是10的倍数开始,重复4次,每10秒重复1次
JobDetail job2 = newJob(ColorJob.class).withIdentity("job2", "group1")
.build();
SimpleTrigger trigger2 = newTrigger()
.withIdentity("trigger2", "group1").startAt(startTime)
.withSchedule(
simpleSchedule().withIntervalInSeconds(10)
.withRepeatCount(4)).build();
// 向 job2传递参数
job2.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "Red");
job2.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);
Date scheduleTime2 = sched.scheduleJob(job2, trigger2);
log.info(job2.getKey().toString() + " will run at: " + scheduleTime2
+ " and repeat: " + trigger2.getRepeatCount()
+ " times, every " + trigger2.getRepeatInterval() / 1000
+ " seconds");
log.info("------- Starting Scheduler ----------------");
// 所有的任务已加入调度器,但调度器未开始之前所有的任务都不会运行
sched.start();
log.info("------- Started Scheduler -----------------");
log.info("------- Waiting 60 seconds... -------------");
try {
Thread.sleep(60L * 1000L);
} catch (Exception e) {
//
}
log.info("------- Shutting Down ---------------------");
sched.shutdown(true);
log.info("------- Shutdown Complete -----------------");
SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
public static void main(String[] args) throws Exception {
JobStateExample example = new JobStateExample();
example.run();
}
}
Example5 错失任务执行策略
/**
* 一个哑任务,用于单元测试
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class StatefulDumbJob implements Job {
// 常量
public static final String NUM_EXECUTIONS = "NumExecutions";
public static final String EXECUTION_DELAY = "ExecutionDelay";
public StatefulDumbJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.err.println("---" + context.getJobDetail().getKey()
+ " executing.[" + new Date() + "]");
// 取出job中的map中的数据,增加并重新放入job的map中
JobDataMap map = context.getJobDetail().getJobDataMap();
int executeCount = 0;
if (map.containsKey(NUM_EXECUTIONS)) {
executeCount = map.getInt(NUM_EXECUTIONS);
}
executeCount++;
map.put(NUM_EXECUTIONS, executeCount);
// 如果包含延迟字段,则模拟任务延迟5秒
long delay = 5000l;
if (map.containsKey(EXECUTION_DELAY)) {
delay = map.getLong(EXECUTION_DELAY);
}
try {
Thread.sleep(delay);
} catch (Exception ignore) {
}
// 完成任务,打印完成语句
System.err.println(" -" + context.getJobDetail().getKey()
+ " complete (" + executeCount + ").");
}
}
public class MisfireExample {
public void run() throws Exception {
Logger log = LoggerFactory.getLogger(MisfireExample.class);
log.info("------- Initializing -------------------");
// 得到调度器的引用
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
log.info("------- Initialization Complete -----------");
log.info("------- Scheduling Jobs -----------");
// 开始时间秒数是15的倍数
Date startTime = nextGivenSecondDate(null, 15);
// 有状态job1每3秒运行1次,但会延迟10秒(任务中睡眠了10秒模拟了执行任务需要10秒)
JobDetail job = newJob(StatefulDumbJob.class).withIdentity(
"statefulJob1", "group1").usingJobData(
StatefulDumbJob.EXECUTION_DELAY, 10000L).build();
SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1")
.startAt(startTime).withSchedule(
simpleSchedule().withIntervalInSeconds(3)
.repeatForever()).build();
Date ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
// 有状态job2每3秒运行1次,但会延迟10秒(任务中睡眠了10秒模拟了执行任务需要10秒)
// job2设置了策略,所以错失后会立即触发,而不会等到下一个触发点
job = newJob(StatefulDumbJob.class).withIdentity("statefulJob2",
"group1").usingJobData(StatefulDumbJob.EXECUTION_DELAY, 10000L)
.build();
trigger = newTrigger().withIdentity("trigger2", "group1").startAt(
startTime).withSchedule(
simpleSchedule().withIntervalInSeconds(3).repeatForever()
// 设置错失触发后的调度策略
.withMisfireHandlingInstructionNowWithExistingCount())
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + ft + " and repeat: "
+ trigger.getRepeatCount() + " times, every "
+ trigger.getRepeatInterval() / 1000 + " seconds");
log.info("------- Starting Scheduler ----------------");
sched.start();
log.info("------- Started Scheduler -----------------");
try {
Thread.sleep(600L * 1000L);
} catch (Exception e) {
}
log.info("------- Shutting Down ---------------------");
sched.shutdown(true);
log.info("------- Shutdown Complete -----------------");
SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
public static void main(String[] args) throws Exception {
MisfireExample example = new MisfireExample();
example.run();
}
//本范例中,触发的间隔被设置为3秒,但是由于任务体执行间睡眠10秒,导致了错失触发的产生。
//实际运行的效果,2个任务执行的间隔为10秒。
//由于丢失触发时,job2的策略是立即触发,而job1是等待下一次机会触发。所以job2会赶在job1的前头,最终运行次数大于job1。
}