一.SimpleTrigger
SimpleTrigger的作用:
在一个指定时间段内执行一次作业任务,
或是在指定的时间间隔内多次执行作业任务。
SimpleTrigger举例
第一个例子:
HelloJob类:
package HelloQuartz.helloQuartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.naming.Context;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
public class HelloJob implements Job {
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");
}
}
HelloScheduler类:
package HelloQuartz.helloQuartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is :" + sf.format(date));
// 创建一个JobDetail示例,将该示例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
//获取距离当前时间4秒钟之后的具体时间
date.setTime(date.getTime()+4000L);
// 距离当前时间4秒钟后执行且仅执行一次任务
SimpleTrigger triger =(SimpleTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.startAt(date)
.build();
// 创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail, triger);
}
}
运行结果:
第二个例子:
package HelloQuartz.helloQuartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is :" + sf.format(date));
// 创建一个JobDetail示例,将该示例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
//获取距离当前时间4秒钟之后的具体时间
date.setTime(date.getTime()+4000L);
// 距离当前时间4秒钟后首次执行任务,之后每隔两秒钟重复执行一次任务
//SimpleTrigger.REPEAT_INDEFINITELY 无限执行
SimpleTrigger triger =(SimpleTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.startAt(date)
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)
.withRepeatCount(3))
.build();
// 创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail, triger);
}
}
需要注意的点:
重复次数可以为0,正整数或是SimpleTrigger.REPEAT_INDEFINITELY常量值。
重复执行间隔必须为0或长整数。
一旦被指定了endTime参数,那么它会覆盖重复次数参数的效果。
二.CronTrigger
CronTrigger的作用:
基于日历的作业调度器
而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用
Cron表达式:
用于配置CronTrigger实例。
是由7个子表达式组成的字符串,描述了时间表的详细信息。
格式:[秒] [分] [小时] [日] [ 月] [周] [年]
, 表示或的关系
-表示至的关系
* 表示每的关系
/ 表示每的关系
6代表星期五
井号代表“第”
3代表第三周
L表示最后“last”
Cron表达式小提示:
1.L和W可以组合使用 日的位置写,意思是每个月的最后一个工作日触发
2.周字段英文字母不区分大小写即MON与mon相同
3.利用工具,在线生成
代码示例:
package HelloQuartz.helloQuartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is :" + sf.format(date));
// 创建一个JobDetail示例,将该示例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
//每秒钟触发一次任务
// CronTrigger triger =(CronTrigger) TriggerBuilder
// .newTrigger()
// .withIdentity("myTrigger", "group1")
// .withSchedule(
// CronScheduleBuilder.cronSchedule("* * * * * ? *"))
//
// .build();
//1.2017年内每天10点15分触发一次
//0 15 10 ? * * 2017
// CronTrigger triger =(CronTrigger) TriggerBuilder
// .newTrigger()
// .withIdentity("myTrigger", "group1")
// .withSchedule(
// CronScheduleBuilder.cronSchedule("0 15 10 ? * * 2017"))
//
// .build();
//2.每天的14点整至14点59分55秒,以及18点整至18点59分55秒,每5秒钟触发一次
// 0/5 * 14,18 * * ?
CronTrigger triger =(CronTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * 14,18 * * ?"))
.build();
//注意下面的没做验证,可能有错误
//3.每月周一至周五的10点15分触发一次
//0 15 10 ? * 2-6 *
//4.每月最后一天的10点15分触发一次
// 0 15 10 L * ?
//5.每月第三个周五的10点15分触发一次
// 0 15 10 6#3 * ? *
// 创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail, triger);
}
}
三.浅谈Scheduler
Scheduler—工厂模式
回顾Quartz三个核心概念
调度器 任务 触发器
StdSchedulerFactory
使用一组参数(Java.util.Properties)来创建和初始化Quartz调度器
配置参数一般存储在quartz.properties中
调用getScheduler方法就能创建和初始化调度器对象
Schduler的主要函数
Date scheduleJob(JobDetail JOBdetail,Trigger trigger)//返回的是程序最近一次将要执行的时间
void start()
void standby()
void shutdown() 将schedule关闭,完全关闭,不能被重新重启
代码示例:
package HelloQuartz.helloQuartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException, InterruptedException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time Is :" + sf.format(date));
// 创建一个JobDetail示例,将该示例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
CronTrigger triger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity("myTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build();
// 创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
System.out.println("scheduled time is:" + sf.format(scheduler.scheduleJob(jobDetail, triger)));
// schedule执行两秒后挂起
// Thread.sleep(2000L);
// scheduler.standby();
// schedule执行两秒后完全关闭
// shutdown(true)表示等待所有正在执行的job执行完毕之后,再关闭scheduler
// shutdown(false)即shutdown()表示直接关闭scheduler
Thread.sleep(2000L);
scheduler.shutdown();
System.out.println("scheduler is shut down?"+scheduler.isShutdown());
// scheduler挂起三秒后继续执行
Thread.sleep(3000L);
scheduler.start();
}
}
运行结果:
Current Exec Time Is :2018-01-02 09:36:50
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
scheduled time is:2018-01-02 09:36:50
Current Exec Time Is :2018-01-02 09:36:51
Hello World
Current Exec Time Is :2018-01-02 09:36:51
Hello World
Current Exec Time Is :2018-01-02 09:36:52
Hello World
Current Exec Time Is :2018-01-02 09:36:53
Hello World
scheduler is shut down?true
Exception in thread "main" org.quartz.SchedulerException: The Scheduler cannot be restarted after shutdown() has been called.
at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:557)
at org.quartz.impl.StdScheduler.start(StdScheduler.java:142)
at HelloQuartz.helloQuartz.HelloScheduler.main(HelloScheduler.java:78)
四.QuartzProperties文件
文档的位置和加载顺序
将文件里面的配置信息复制下来
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
把代码全部复制进去
保存并quartz.properties命名
程序会优先读取工程目录下的这个文件,假如没有这个文件,就会默认去读架包里面的文件。
组成部分:
调度器属性:org.quartz.scheduler.instanceName属性用来区分特定的调度器实例,可以按照功能用途来给调度器起名。org.quartz.scheduler.instanceId属性和前者一样,也允许任何字符串,但这个值必须是在所有调度器实例中是唯一的,尤其是在一个集群当中,作为集群的唯一key。假如你想Quartz帮你生成这个值的话,可以设置为AUTO。
线程池属性:ThreadCount决定了quartz有多少个工作者线程被创建,原则上是要处理的job越多,需要处理的工作线程就越多。
threadPriority:设置工作者线程的优先级。最大值是10,最小值是1,正常值是5(默认)
org.quartz.threadPool.class 是一个实现了org.quartz.threadPool接口的权限名称
作业存储设置:描述了再调度器实例的生命周期中,Job和Trigger信息是如何被存储的。
插件配置:满足特定需求用到的Quartz插件的配置。