http://blog.csdn.net/zixiao217/article/details/53075009

Quartz的主要接口类是Schedule、Job、Trigger,而触发器Trigger就是定时任务的触发时间,它规定安排了关联的任务会在什么时候执行,并且表明了再次执行的时机。

Quartz提供了多种触发器:

我们详细讲解最常用的两种触发器:简单触发器SimpleTrigger基于Cron表达式的触发器CronTrigger

(本文章分享在CSDN平台,更多精彩请阅读 东陆之滇的csdn博客:http://blog.csdn.net/zixiao217)

简单触发器SimpleTrigger

SimpleTrigger是接口Trigger的一个具体实现,它可以触发一个已经安排进调度程序(任务执行计划)的任务,并可以指定时间间隔重复执行该任务。

SimpleTrigger 包含几个特点:开始时间、结束时间、重复次数以及重复执行的时间间隔。

重复的次数可以是零,一个正整数,或常量SimpleTrigger.REPEAT_INDEFINITELY。 
重复执行的时间间隔可以是零,或者long类型的数值表示毫秒。值得注意的是,零重复间隔会造成触发器同时发生(或接近同时作为调度管理)。 
“结束时间”的属性会重写重复的次数,这可能是有用的,如果你想创建一个触发器,如每10秒触发一次,直到一个给定的时刻,而不是要计算的次数,它会在开始时间和结束时间重复执行。结束时间一到,就算你指定了重复次数很多次(比如执行10W次),但是时间一到它将不再执行。

SimpleTrigger 实例创建依赖于TriggerBuilder 和SimpleScheduleBuilder ,使用Quartz提供的DSL风格创建触发器实例, 
首先静态引入builder,引入时间builder——DateBuilder:

import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.DateBuilder.*:
我们可以创建很多不同形式的触发器:

创建一个指定时间开始执行,但是不重复的触发器

使用startAt(Java.util.Date)设置触发器的第一次执行时间:

SimpleTrigger trigger = (SimpleTrigger) newTrigger()
.withIdentity("trigger1", "group1")
.startAt(myStartTime) // some Date
.forJob("job1", "group1") // identify job with name, group strings
.build();

创建一个指定时间开始执行,每10s执行一次,共执行10次的触发器

使用SimpleScheduleBuilderwithIntervalInSeconds(N)方法可以指定间隔N秒就执行一次;withRepeatCount(M)可以指定执行次数M。

trigger = newTrigger()
.withIdentity("trigger3", "group1")
.startAt(myTimeToStartFiring) // if a start time is not given (if this line were omitted), "now" is implied
.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(10)) // note that 10 repeats will give a total of 11 firings
.forJob(myJob) // identify job with handle to its JobDetail itself
.build();

SimpleScheduleBuilder有很多类似的方法,API如下:

创建一个在未来第五分钟的时候执行一次的触发器

使用DateBuilder的futureDate方法可以指定在未来时间执行。

trigger = (SimpleTrigger) newTrigger()
.withIdentity("trigger5", "group1")
.startAt(futureDate(5, IntervalUnit.MINUTE))
.forJob(myJobKey) /* job的jobKey*/
.build();

创建一个马上执行、每个5分钟执行、知道22:00结束执行的触发器

使用TriggerBuilder的startNow()方法立即触发(scheduler调用start时算起,视优先级而定); 
withIntervalInMinutes(5)每个5分钟执行一次; 
repeatForever()一直重复; 
endAt(dateOf(22, 0, 0))知道22:00终结触发器:

trigger = newTrigger()
.withIdentity("trigger7", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInMinutes(5)
.repeatForever())
.endAt(dateOf(22, 0, 0))
.build();

创建一个在偶数小时执行、每两个小时执行一次的触发器

trigger = newTrigger()
.withIdentity("trigger8") // group未指定,则会使用默认的组名
.startAt(evenHourDate(null)) // 在下一个偶数小时开始执行(00:00:00、02:00:00、04:00:00等)
.withSchedule(simpleSchedule()
.withIntervalInHours(2) //每隔两小时执行一次
.repeatForever()) //一直重复执行
.build();

值得注意的是,如果没有调用startAt(..)方法,默认使用startNow()。 
建议花点时间逐个尝试使用TriggerBuilderSimpleScheduleBuilder DateBuilder提供的API方法以加深理解。

关于简单触发器”熄火”的指令

SimpleTrigger 包含一些指令在它”熄火”时可以告知Quartz怎么去处理。这些指令包含在SimpleTrigger 的常量中。

  • REPEAT_INDEFINITELY - 用于表示触发器的“重复计数”是不确定的。或者换句话说,触发应该不断重复直到触发的结尾时间戳
  • MISFIRE_INSTRUCTION_FIRE_NOW - 如果熄火,该指令会告诉Quartz应该马上再次触发
  • MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT - 如果熄火,该指令会告诉Quartz马上执行并计数累计到已经执行的次数当中去,如果结束时间已经过了,则不会再执行。
  • MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT - 如果熄火,会告诉Quartz想要现在就执行一次(即使现在不是它原本计划的触发时间)
  • MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT - 如果熄火,会告诉Quartz在下一次执行时间再次开始执行

一个使用”熄火”策略的触发器示例:

trigger = newTrigger()
.withIdentity("trigger7", "group1")
.withSchedule(simpleSchedule()
.withIntervalInMinutes(5)
.repeatForever()
.withMisfireHandlingInstructionNextWithExistingCount())
.build();

基于Cron表达式的触发器CronTrigger

CronTrigger通常使用得比SimpleTrigger等多一些。特别是基于日历的概念,而不是对具体间隔的行为。

通过CronTrigger,你可以指定”每个星期五的中午”、”每个工作日上午9:30”,甚至是”一月的每星期一的上午9点至10点之间的每5分钟,星期三和星期五”(这长串直接懵逼了…)执行。

Cron表达式

首先了解Cron表达式,它是用于配制CronTrigger实例的。Cron表达式,实际上是由七个子表达式组成的字符串,它描述了不同的调度细节。这些子表达式是用空格分隔的,并表示: 
秒 
分 
时 
月中的天 
月 
周中的天 
年(可选项)

例如: “0 0 12 ? * WED” 表示 “个星期三的12点”

单个子表达式可以包含范围和/或列表,例如:

"0 0 7 ? * MON-FRI" 表示 "每个工作日的7点"

"0 0 19 ? * MON,WED,FRI" 表示 "周一、周三和周五的19点"

"0 0 14 ? * MON-WED,SAT" 表示 "周一到周三以及周六的14点"

Cron表达式的规则说明

所有字段都有一组可以指定的有效值。

  • 数字 0 到 59 可以表示秒和分
  • 0到23可以表示小时
  • 月中的天可以使用1到31的数值, 但是你要注意该月的天数!
  • 月用0 到 11之间的数值表示, 或者使用JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV 和 DEC来表示1-12月
  • 一周中的天试用1到7表示 (1 表示 周日) 或者使用 SUN, MON, TUE, WED, THU, FRI 和 SAT

创建CronTrigger

CronTrigger实例使用TriggerBuilder 和 CronScheduleBuilder创建,静态引入:

import static org.quartz.TriggerBuilder.*;
import static org.quartz.CronScheduleBuilder.*;
import static org.quartz.DateBuilder.*:

创建一个8到17点间每两分钟执行一次的Cron触发器:

cronTrigger1 = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(cronSchedule("0 0/2 8-17 * * ?"))
.forJob("myJob", "group1")
.build();

创建一个每天10:42执行的Cron触发器:

cronTrigger2 = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(dailyAtHourAndMinute(10, 42))
.forJob(job.getKey())
.build();
/*或者
*我更喜欢下面这种方式
*/
cronTrigger3 = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(cronSchedule("0 42 10 * * ?"))
.forJob(job.getKey())
.build();

关于CronTrigger”熄火”的指令

CronTrigger同样包含一些指令在它”熄火”时可以告知Quartz怎么去处理。

  • MISFIRE_INSTRUCTION_FIRE_ONCE_NOW - 如果熄火,该指令会告诉Quartz希望马上再次触发
  • MISFIRE_INSTRUCTION_DO_NOTHING - 如果熄火,该指令会告诉Quartz下一次执行时间到来时再执行,并不想马上执行
cronTrigger4MisfireInstruction = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(cronSchedule("0 0/2 8-17 * * ?")
.withMisfireHandlingInstructionFireAndProceed())
.forJob("myJob", "group1")
.build();

史上最详细的Cron表达式的举例讲解

这里列举很多最常用的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 * * ? 每天的14:00到14:59期间每分钟执行
0 0/5 14 * * ? 每天的14:00到14:55每隔5分钟执行
0 0/5 14,18 * * ? 每天的14:00到14:55每隔5分钟执行和18:00到18:55每隔5分钟执行
0 0-5 14 * * ? 每天的14:00到14:05执行
0 10,44 14 ? 3 WED 三月的每一个周三的14:10和14:44执行
0 15 10 ? * MON-FRI 工作日每天的10:15:00执行
0 15 10 15 * ? 每个月的第15天的10:15:00执行
0 15 10 L * ? 每个月最后一天的10:15:00执行
0 15 10 ? * 6L 每个月最后一个周五的10:15:00执行
0 15 10 ? * 6L 2002-2005 2002, 2003, 2004, 和2005年每个月最后一个周五的10:15:00执行
0 15 10 ? * 6#3 每个月的第三个周五的10:15:00执行
0 0 12 1/5 * ? 每个月的第一天的12:00:00开始执行,每隔5天间隔执行
0 11 11 11 11 ? 每年的11月11日11:11:00执行

(转)Java任务调度框架Quartz入门教程指南(四)Quartz任务调度框架之触发器精讲SimpleTrigger和CronTrigger、最详细的Cron表达式范例的更多相关文章

  1. Veins(车载通信仿真框架)入门教程(四)——调试及记录结果

    Veins(车载通信仿真框架)入门教程(四)——调试及记录结果 在Veins入门教程(三)最后的动图中(如下图)可以看到大大小小的光圈,这个怎么实现的呢? 很简单,以收到RTS消息为例,通过finHo ...

  2. (转)Java任务调度框架Quartz入门教程指南(二) 使用job、trigger、schedule调用定时任务

    http://blog.csdn.net/zixiao217/article/details/53044890 读完第一节,我们已经对Quartz有了一个大体的认识,它可以定时帮我们执行一些处理程序, ...

  3. (转)Java任务调度框架Quartz入门教程指南(三)任务调度框架Quartz实例详解深入理解Scheduler,Job,Trigger,JobDetail

    http://blog.csdn.net/zixiao217/article/details/53053598 首先给一个简明扼要的理解: Scheduler 调度程序-任务执行计划表,只有安排进执行 ...

  4. Veins(车载通信仿真框架)入门教程(三)——多跳路由实现指导

    Veins(车载通信仿真框架)入门教程(三)——多跳路由实现指导 Veins(车载通信仿真框架)入门教程(三)——多跳路由实现指导 必要的message类实现 从下面开始是在veins/src/vei ...

  5. Veins(车载通信仿真框架)入门教程(二)——调用第三方库

    Veins(车载通信仿真框架)入门教程(二)——调用第三方库 在借助Veins进行自己的研究时我们经常需要实现一些比较复杂的功能,有时就需要借助第三方库的帮助. 博主的研究需要使用神经网络,但是自己编 ...

  6. 无废话ExtJs 入门教程十四[文本编辑器:Editor]

    无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功 ...

  7. WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]

    WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...

  8. WCF入门教程(四)通过Host代码方式来承载服务

    WCF入门教程(四)通过Host代码方式来承载服务 之前已经讲过WCF对外发布服务的具体方式. WCF入门教程(一)简介 Host承载,可以是web,也可以是控制台程序等等.比WebService有更 ...

  9. Docker入门教程(四)Docker Registry

    Docker入门教程(四)Docker Registry [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第四篇,介绍了Docker Registry,它 ...

随机推荐

  1. C/C++异常处理机制

    1.C语言异常处理   1.1 异常终止   标准C库提供了abort()和exit()两个函数,它们可以强行终止程序的运行,其声明处于<stdlib.h>头文件中.这两个函数本身不能检测 ...

  2. bootstrap日期控件

    http://www.bootcss.com/p/bootstrap-datetimepicker/ <link href="js/b/css/bootstrap-datetimepi ...

  3. Cannot update identity column &#39;XXX&#39;

    Sqlserver -- 怎样改动设置主键的id能够手动更新? #1 打开表的设计界面 #2 将主键id的is Identity的属性改成No 这样就能够通过Update语句来更新表的主键id了. 怎 ...

  4. 利用rman自己主动备份转储spfile

    利用rman自己主动备份转储spfile [情景简单介绍] 生产环境丢失了server的參数文件,rman已开启自己主动备份设置. [操作过程简述] ----启动rman $rman target / ...

  5. 8.30 "我什么都不会"

    /* 抢名额第一场 GG "我什么都不会阿" 这场磕死在E题了 按说应该能想到费马小定理 毕竟p is a prime 别的队都过了 大家都比较熟悉的就只有这一个 然后还有I题一开 ...

  6. sql_server_action

    ''' SELECT * FROM Info_Roles WHERE Flag=1 LIMIT 2; select top y * from 表 where 主键 not in(select top ...

  7. TGraphicControl和TCustomControl自绘过程的理论解释

    TGraphicControl = class(TControl) // 这个类实在是简单,因为所有事情都已经委托给它的父Win控件了,只要管自己即可 private FCanvas: TCanvas ...

  8. bzoj 4537 最小公倍数

    给定一张N个顶点M条边的无向图 每条边上带有权值 所有权值都可以分解成2^a*3^b的形式 q个询问,每次询问给定四个参数u.v.a和b,请你求出是否存在一条顶点u到v之间的路径,使得路径依次经过的边 ...

  9. 【转载】[Oracle] Linux下手动创建数据库过程

    今天发现一个Oracle测试库的字符集设置不正确,原本的字符集是UTF-8,正确的字符集应该是ZHS16GBK,因为UTF-8是ZHS16GBK的超集,无法修改,只能重建数据库,幸好该测试库上还没有数 ...

  10. 清北刷题班day3 morning

    P99zhx: 竞赛时间:???? 年?? 月?? 日??:??-??:??题目名称 a b c名称 a b c输入 a.in b.in c.in输出 a.out b.out c.out每个测试点时限 ...