您的位置:首页 > 编程语言 > Java开发

Java定时任务调度工具详解之Quartz篇(中级)二:SimpleTrigger& CronTrigger&浅谈Scheduler&QuartzProperties文件

2017-12-29 17:30 756 查看

一.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插件的配置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 任务调度 quartz