1.Quartz 是用来完成任务调度的。

2.Quartz 的三个核心概念:调度器、任务、触发器。

(1)Job:通过实现该接口来定义需要执行的任务。

public interface Job {

    /**
* Called by the <code>{@link Scheduler}</code> when a <code>{@link Trigger}</code> fires that is associated with the <code>Job</code>.
*/
void execute(JobExecutionContext context) throws JobExecutionException;
}

(2)JobDetail:Quartz 在每次执行 Job 时,都重新创建一个 Job 实例,所以它不是直接接受一个 Job 的实例,而是接受 Job 的一个实现类,以便运行时通过反射区实例化 Job。

JobDtail 就是用来描述 Job 的实现类以及其他相关的静态信息。

package org.quartz;

import java.io.Serializable;

/**
* Conveys the detail properties of a given <code>Job</code> instance. JobDetails are
* to be created/defined with {@link JobBuilder}.
*
* <p>
* Quartz does not store an actual instance of a <code>Job</code> class, but
* instead allows you to define an instance of one, through the use of a <code>JobDetail</code>.
* </p>
*
* <p>
* <code>Job</code>s have a name and group associated with them, which
* should uniquely identify them within a single <code>{@link Scheduler}</code>.
* </p>
*
* <p>
* <code>Trigger</code>s are the 'mechanism' by which <code>Job</code>s
* are scheduled. Many <code>Trigger</code>s can point to the same <code>Job</code>,
* but a single <code>Trigger</code> can only point to one <code>Job</code>.
* </p>*/
public interface JobDetail extends Serializable, Cloneable { public JobKey getKey(); public String getDescription(); public Class<? extends Job> getJobClass(); public JobDataMap getJobDataMap(); public boolean isDurable(); public boolean isPersistJobDataAfterExecution(); public boolean isConcurrentExectionDisallowed(); public boolean requestsRecovery(); public Object clone(); public JobBuilder getJobBuilder(); }

(3)Trigger(中文"触发"的意思):描述出发 Job 执行的时间触发规则。

package org.quartz;

import java.io.Serializable;
import java.util.Comparator;
import java.util.Date;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.ScheduleBuilder;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey; /**
* The base interface with properties common to all <code>Trigger</code>s -
* use {@link TriggerBuilder} to instantiate an actual Trigger.
*
* <p>
* <code>Triggers</code>s have a {@link TriggerKey} associated with them, which
* should uniquely identify them within a single <code>{@link Scheduler}</code>.
* </p>
*
* <p>
* <code>Trigger</code>s are the 'mechanism' by which <code>Job</code>s
* are scheduled. Many <code>Trigger</code>s can point to the same <code>Job</code>,
* but a single <code>Trigger</code> can only point to one <code>Job</code>.
* </p>
*
* <p>
* Triggers can 'send' parameters/data to <code>Job</code>s by placing contents
* into the <code>JobDataMap</code> on the <code>Trigger</code>.
* </p>
*
* @see TriggerBuilder
* @see JobDataMap
* @see JobExecutionContext
* @see TriggerUtils
* @see SimpleTrigger
* @see CronTrigger
* @see CalendarIntervalTrigger
*
* @author James House
*/
public interface Trigger extends Serializable, Cloneable, Comparable<Trigger> {
long serialVersionUID = -3904243490805975570L;
int MISFIRE_INSTRUCTION_SMART_POLICY = 0;
int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;
int DEFAULT_PRIORITY = 5; TriggerKey getKey(); JobKey getJobKey(); String getDescription(); String getCalendarName(); JobDataMap getJobDataMap(); int getPriority(); boolean mayFireAgain(); Date getStartTime(); Date getEndTime(); Date getNextFireTime(); Date getPreviousFireTime(); Date getFireTimeAfter(Date var1); Date getFinalFireTime(); int getMisfireInstruction(); TriggerBuilder<? extends Trigger> getTriggerBuilder(); ScheduleBuilder<? extends Trigger> getScheduleBuilder(); boolean equals(Object var1); int compareTo(Trigger var1); public static class TriggerTimeComparator implements Comparator<Trigger>, Serializable {
private static final long serialVersionUID = -3904243490805975570L; public TriggerTimeComparator() {
} public static int compare(Date nextFireTime1, int priority1, TriggerKey key1, Date nextFireTime2, int priority2, TriggerKey key2) {
if(nextFireTime1 != null || nextFireTime2 != null) {
if(nextFireTime1 == null) {
return 1;
} if(nextFireTime2 == null) {
return -1;
} if(nextFireTime1.before(nextFireTime2)) {
return -1;
} if(nextFireTime1.after(nextFireTime2)) {
return 1;
}
} int comp = priority2 - priority1;
return comp != 0?comp:key1.compareTo(key2);
} public int compare(Trigger t1, Trigger t2) {
return compare(t1.getNextFireTime(), t1.getPriority(), t1.getKey(), t2.getNextFireTime(), t2.getPriority(), t2.getKey());
}
} public static enum CompletedExecutionInstruction {
NOOP,
RE_EXECUTE_JOB,
SET_TRIGGER_COMPLETE,
DELETE_TRIGGER,
SET_ALL_JOB_TRIGGERS_COMPLETE,
SET_TRIGGER_ERROR,
SET_ALL_JOB_TRIGGERS_ERROR; private CompletedExecutionInstruction() {
}
} public static enum TriggerState {
NONE,
NORMAL,
PAUSED,
COMPLETE,
ERROR,
BLOCKED; private TriggerState() {
}
}
}

主要有两个实现类:

  • SimpleTrigger:当仅需要触发一次或者以固定间隔周期执行。
  • CronTrigger:可以通过 Cron 表达式定义出各种复杂的调度方案。

(4)Calendar:一些日历特定时间点的集合。一个 Trigger 可以和多个 Calendar 关联,以便包含或排除某些时间点。

(5)Scheduler:一个 Quartz 的独立运行容器,Trigger 和 JobDtail 可以注册到 Scheduler 中。

Scheduler 可以将 Trigger 绑定到某一个 JobDetail 中,这样当 Trigger 被触发时,对应的 Job 就被执行。

一个 Job 可以有多个对应的 Trigger ,但是一个 Trigger 只能对应一个 Job。

3. HelloWorld

(1)步骤:

  • 实现 Job 接口,可使 Java 类变为可调度的任务
  • 创建描述 Job 的 JobDetail 对象
  • 创建 Trigger 对象
  • 设置触发 Job 执行的时间规则
  • 通过 SchedulerFactory 获取 Scheduler 对象
  • 向 SchedulerFactory 中注册 JobDetail 和 Trigger
  • 启动调度任务

(2)SimpleTrigger

/**
* @author solverpeng
* @create 2016-09-25-14:56
*/
public class HelloWorld { public static void main(String[] args) throws SchedulerException, ParseException { JobDetailImpl jobDetail = new JobDetailImpl(); jobDetail.setGroup("test-group"); jobDetail.setName("test-name");
jobDetail.setJobClass(MyJob.class); SimpleTriggerImpl trigger = new SimpleTriggerImpl();
trigger.setName("test-trigger-name");
trigger.setGroup("test-trigger-group");
trigger.setStartTime(new Date());
trigger.setRepeatCount(5);
trigger.setRepeatInterval(1000*5); SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }

(3)CronTrigger

Cron 表达式1:

  • 由6或7个空格分割的时间字段组成
  • 对特殊字符的大小写不敏感
  • 从左到右时间范围越来越大:秒 分 时 日 月 星期 年(可选)
  • 秒:范围:0-59,允许特殊字符 ", - * /"
  • 分:范围:0-59,允许特殊字符 ", - * /"
  • 小时:范围:0-23
  • 日期:范围:1-31
  • 星期:范围:1-7(需要用英文简写表示)
  • 年:范围:控制或 1970-2099

Cron 表达式2:

  • * :可用于所有字段,表示每一个时刻。e: * 分钟时段表示每分钟
  • ? :只能使用在日期和星期字段,表示一个毫无意义的值。相当于占位符。(日期和星期字段必须有一个 ? ,不能使用 * 替代)
  • - :表示一个范围。e: 10-12 使用在小时字段,表示10点、11点、12点
  • , :表示一个列表值。e:在星期字段中使用 MON,WED,FRI,表示星期一,星期三,星期五
  • / :x/y 表示一个等步长序列,x 为起始值,y 为增量步长。
    • e1:在分钟字段使用 0/15 ,则表示 0,15,30 和 45 秒;
    • e2:5/15,表示5,20,35,50。
    • */y 等同于 0/y。
  • L :只在日期和星期字段中使用,代表 Last。
    • 使用在日期字段,表示这个月的最后一天;
    • 使用在星期字段,表示星期六。
    • 若 L 出现在星期字段里,且前面有一个数值X,则表示这个月的最后星期X,例如 6L 表示该月的最后一个星期五。
  • W :只能出现在日期字段中,是对前导日期的修饰,表示离该日期最近的工作日。
    • e1:15W 表示离该月15号最近的工作日,若15号是星期六,则匹配14号,若15号是星期日,则匹配16号,若15号是星期二,则匹配15号。
    • 关联的匹配日期不能跨月。如用户指定1W,若1号是星期六,则匹配3号
    • W 只能指定单一日期,而不能指定日期范围
  • LW :在日期字段可以组合使用LW,值 当月的最后一个工作日
  • # :只能在星期字段中使用,表示当月某个工作日,如:6#3 表示当月的第三个星期5,4#5 表示当月第5个星期三。
  • C :该字段只在日期和星期字段中使用,代表 Canlendar。指计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。
    • 5C在日期字段中相当于 5 日以后的第一天  
    • 1C在星期字段中相当于星期日后的第一天

Cron表达式示例

  • 0 0 12 * * ?:每天中午12点触发
  • 0 15 10 ? * *:每天上午10:15触发
  • 0 15 10 * ? *: 每天上午10:15触发
  • 0 15 10 * * ?: 每天上午10:15触发
  • 0 15 10 * * ? 2005: 2005年的每天上午10:15触发
  • 0 * 14 * * ?:在每天下午2点到下午2:59期间的每1分钟触发
  • 0 0/5 14 * * ?:在每天下午2点到下午2:55期间的每5分钟触发
  • 0 0/5 14, 18 * * ?:在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟,触发
  • 0 0-5 14 * * ?:在每天下午2点到下午2:05期间的每1分钟触发
  • 0 10,44 14 ? 3 WED:每年三月的星期三的下午2:10和2:44触发
  • 0 15 10 ? * MON-FRI:周一至周五的上午10:15 触发
  • 0 15 10 15 * ?:每月15日上午10:15 触发
  • 0 15 10 L * ?:每月最后一日的上午10:15 触发
  • 0 15 10 ? * 6L:每月的最后一个星期五上午10:15 触发
  • 0 15 10 ? * 6L 2002-2005:2002年至2005年的每月的最后一个星期五上午10:15触发
  • 0 15 10 ? * 6#3:每月的第三个星期五上午10:15触发

例子:

/**
* @author solverpeng
* @create 2016-09-25-14:56
*/
public class HelloWorld {
public static void main(String[] args) throws SchedulerException, ParseException { JobDetailImpl jobDetail = new JobDetailImpl(); jobDetail.setGroup("test-group"); jobDetail.setName("test-name");
jobDetail.setJobClass(MyJob.class); CronTriggerImpl trigger = new CronTriggerImpl(); trigger.setCronExpression("0/5 56 15 ? 9 SUN"); trigger.setStartTime(new Date());
trigger.setName("test-trigger-name"); trigger.setGroup("test-trigger-group"); SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start(); } }

官方 Demo:

package com.nucsoft.quartz;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory; import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger; /**
* @author solverpeng
* @create 2016-09-25-16:49
*/
public class HelloWorld { public static void main(String[] args) throws SchedulerException {
// define the job and tie it to our MyJob class
JobDetail job = newJob(MyJob.class).withIdentity("job1", "group1").build(); // Trigger the job to run now, and then repeat every 40 seconds
Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow().withSchedule(
simpleSchedule().withIntervalInSeconds(40).repeatForever()).build();
// Grab the Scheduler instance from the Factory
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger); // and start it off
scheduler.start();
} }

4.总结

介绍了Quartz的几个核心概念,Cron 表达式,以及 Quartz 的 HelloWorld。Job 是用来定义要完成的任务,JobDetail用来描述它,Trigger 是一个触发器,用于触发任务,它们统一由 Scheduler

来管理。其中需要注意一点的是,国外每个星期的开始是从 星期日开始的,所以 6 表示星期五。

Quartz —— 从 HelloWorld 开始的更多相关文章

  1. quartz(1)

    关于定时任务的操作方法,java语言本身具有 Timer 来解决,但Timer 作用起来不是特别的舒服,由于项目的需要,使用了Quartz 这个调度框架,现把学习过程记录下来,方便以后查阅. 本教程是 ...

  2. Quartz.net2.2初体验

    简介:Quartz.net是一个开源的作用调度框架,非常强大,能够通过简单的配置帮助我们定时具体的操作.相对于我们用的线程里面while(true)然后sleep来执行某个操作,应该算的上是高端,大气 ...

  3. quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  4. 定时组件quartz系列<三>quartz调度机制调研及源码分析

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  5. Spring中Quartz的配置

    Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz,下面就看看在Spring中怎样配置Quartz: 首先,来写一个测试被调度的类:(QuartzHelloWorldJ ...

  6. (1)quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析 原文地址:http://demo.netfoucs.com/gklifg/article/details/27090179 引言quartz集群架构调 ...

  7. quartz群调查调度机制和源代码分析

    pageId=85056282#quartz集群调度机制调研及源代码分析-quartz2.2.1集群调度机制调研及源代码分析" style="color:rgb(59,115,17 ...

  8. quartz笔记

    首先网络上的很多教程经常有错(信息过载了),其主要原因是版本发生了变化,例如quartz1和2之间还是有不少差别的,导致查找资料的人浪费了不少时间.所以无论教程如何写,都建议读者首先学习官网的教程,如 ...

  9. 【Quartz】1、Quartz使用说明

    简介 Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制.Quartz 允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和触发器的多对多关系,还 ...

随机推荐

  1. 微信小程序体验(1):携程酒店机票火车票

    在 12 月 28 日微信公开课上,张小龙对微信小程序的形态进行了阐释,小程序有四个特定:无需安装.触手可及.用完即走.无需卸载. 由于携程这种订酒店.火车票和机票等工具性质非常强的服务,非常符合张小 ...

  2. Linux学习笔记(一):常用命令

    经过统计Linux中能够识别的命令超过3000种,当然常用的命令就远远没有这么多了,按照我的习惯,我把已经学过的Linux常用命令做了以下几个方面的分割: 1.文件处理命令 2.文件搜索命令 3.帮助 ...

  3. Immutable(不可变)集合

    不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 对不可靠的客户代 ...

  4. EQueue 2.0 性能测试报告

    前言 最近用了几个月的时间,一直在对EQueue做性能优化.到现在总算告一段落了,现在把一些优化的结果分享给大家.EQueue是一个分布式的消息队列,设计思路基本和阿里的RocketMQ一致,只是是用 ...

  5. API Monitor简介(API监控工具)

    API Monitor是一个免费软件,可以让你监视和控制应用程序和服务,取得了API调用. 它是一个强大的工具,看到的应用程序和服务是如何工作的,或跟踪,你在自己的应用程序的问题. 64位支持 API ...

  6. JS模块化开发:使用SeaJs高效构建页面

    一.扯淡部分 很久很久以前,也就是刚开始接触前端的那会儿,脑袋里压根没有什么架构.重构.性能这些概念,天真地以为前端===好看的页面,甚至把js都划分到除了用来写一些美美的特效别无它用的阴暗角落里,就 ...

  7. ABP(现代ASP.NET样板开发框架)系列之7、ABP Session管理

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之7.ABP Session管理 ABP是“ASP.NET Boilerplate Project (ASP.NET ...

  8. ABP框架 - 集成OWIN

    文档目录 如果你在应用中同时使用Asp.net Mvc和Asp.net Web API,你需要在你的项目里添加Abp.Owin的nuget包(通常是Web项目)然后在你的OWIN的Startup文件里 ...

  9. Atitit 输入法原理与概论ati use

    Atitit 输入法原理与概论ati use 1.1. 输入法技术点1 1.2. 参考多多输入法设置2 1.3. Attilax博客集合知识点2 1.4. 输入法的书籍当当几乎没有..都是打字的.2 ...

  10. Atitit 知识管理的重要方法 数据来源,聚合,分类,备份,发布 搜索

    Atitit 知识管理的重要方法 数据来源,聚合,分类,备份,发布 搜索 1.1. Rss 简易信息聚合(也叫聚合内容 Really Simple Syndication1 1.1. Rss 简易信息 ...