任务调度框架Quartz(四)Quartz任务调度框架之触发器精讲SimpleTrigger和CronTrigger、最详细的Cron表达式范例

本文深入解析Quartz框架中的定时任务触发器,包括SimpleTrigger和CronTrigger的使用方法及特性,通过实例演示如何创建各种复杂的定时任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

Quartz提供了多种触发器: 

这里写图片描述

 

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

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

简单触发器SimpleTrigger

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

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

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

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

<span style="color:#000000"><code><span style="color:#000088">import</span> <span style="color:#000088">static</span> org.quartz.TriggerBuilder.*;
<span style="color:#000088">import</span> <span style="color:#000088">static</span> org.quartz.SimpleScheduleBuilder.*;
<span style="color:#000088">import</span> <span style="color:#000088">static</span> org.quartz.DateBuilder.*:</code></span>

我们可以创建很多不同形式的触发器:

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

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

<span style="color:#000000"><code>SimpleTrigger trigger = (SimpleTrigger) newTrigger()
    <span style="color:#009900">.withIdentity</span>(<span style="color:#009900">"trigger1"</span>, <span style="color:#009900">"group1"</span>)
    <span style="color:#009900">.startAt</span>(myStartTime) // some Date
    <span style="color:#009900">.forJob</span>(<span style="color:#009900">"job1"</span>, <span style="color:#009900">"group1"</span>) // identify job with name, group strings
    <span style="color:#009900">.build</span>()<span style="color:#880000">;</span></code></span>

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

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

<span style="color:#000000"><code>trigger = newTrigger()
    .withIdentity(<span style="color:#009900">"trigger3"</span>, <span style="color:#009900">"group1"</span>)
    .startAt(myTimeToStartFiring)  // <span style="color:#000088">if</span> a start <span style="color:#4f4f4f">time</span> <span style="color:#000088">is</span> <span style="color:#000088">not</span> given (<span style="color:#000088">if</span> this line were omitted), <span style="color:#009900">"now"</span> <span style="color:#000088">is</span> implied
    .withSchedule(simpleSchedule()
        .withIntervalInSeconds(<span style="color:#006666">10</span>)
        .withRepeatCount(<span style="color:#006666">10</span>)) // note that <span style="color:#006666">10</span> repeats will give a total <span style="color:#000088">of</span> <span style="color:#006666">11</span> firings
    .forJob(myJob) // identify job <span style="color:#000088">with</span> handle <span style="color:#000088">to</span> its JobDetail itself                   
    .build();</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

这里写图片描述

 

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

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

<span style="color:#000000"><code>trigger = (SimpleTrigger) newTrigger()
    <span style="color:#009900">.withIdentity</span>(<span style="color:#009900">"trigger5"</span>, <span style="color:#009900">"group1"</span>)
    <span style="color:#009900">.startAt</span>(futureDate(<span style="color:#006666">5</span>, IntervalUnit<span style="color:#009900">.MINUTE</span>)) 
    <span style="color:#009900">.forJob</span>(myJobKey) <span style="color:#880000">/* job的jobKey*/</span>
    <span style="color:#009900">.build</span>()<span style="color:#880000">;</span></code></span>

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

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

<span style="color:#000000"><code>trigger = newTrigger()
    <span style="color:#009900">.withIdentity</span>(<span style="color:#009900">"trigger7"</span>, <span style="color:#009900">"group1"</span>)
    <span style="color:#009900">.startNow</span>()
    <span style="color:#009900">.withSchedule</span>(simpleSchedule()
        <span style="color:#009900">.withIntervalInMinutes</span>(<span style="color:#006666">5</span>)
        <span style="color:#009900">.repeatForever</span>())
    <span style="color:#009900">.endAt</span>(dateOf(<span style="color:#006666">22</span>, <span style="color:#006666">0</span>, <span style="color:#006666">0</span>))
    <span style="color:#009900">.build</span>()<span style="color:#880000">;</span></code></span>

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

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

值得注意的是,如果没有调用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在下一次执行时间再次开始执行

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

<span style="color:#000000"><code>trigger = newTrigger()
    <span style="color:#009900">.withIdentity</span>(<span style="color:#009900">"trigger7"</span>, <span style="color:#009900">"group1"</span>)
    <span style="color:#009900">.withSchedule</span>(simpleSchedule()
        <span style="color:#009900">.withIntervalInMinutes</span>(<span style="color:#006666">5</span>)
        <span style="color:#009900">.repeatForever</span>()
        <span style="color:#009900">.withMisfireHandlingInstructionNextWithExistingCount</span>())
    <span style="color:#009900">.build</span>()<span style="color:#880000">;</span></code></span>

基于Cron表达式的触发器CronTrigger

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

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

Cron表达式

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

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

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

<span style="color:#000000"><code><span style="color:#009900">"0 0 7 ? * MON-FRI"</span> 表示 <span style="color:#009900">"每个工作日的7点"</span>

<span style="color:#009900">"0 0 19 ? * MON,WED,FRI"</span> 表示 <span style="color:#009900">"周一、周三和周五的19点"</span>

<span style="color:#009900">"0 0 14 ? * MON-WED,SAT"</span> 表示 <span style="color:#009900">"周一到周三以及周六的14点"</span>
</code></span>

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创建,静态引入:

<span style="color:#000000"><code><span style="color:#000088">import</span> <span style="color:#000088">static</span> org.quartz.TriggerBuilder.*;
<span style="color:#000088">import</span> <span style="color:#000088">static</span> org.quartz.CronScheduleBuilder.*;
<span style="color:#000088">import</span> <span style="color:#000088">static</span> org.quartz.DateBuilder.*:</code></span>

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

<span style="color:#000000"><code>cronTrigger1 = newTrigger()
                <span style="color:#009900">.withIdentity</span>(<span style="color:#009900">"trigger3"</span>, <span style="color:#009900">"group1"</span>)
                <span style="color:#009900">.withSchedule</span>(cronSchedule(<span style="color:#009900">"0 0/2 8-17 * * ?"</span>))
                <span style="color:#009900">.forJob</span>(<span style="color:#009900">"myJob"</span>, <span style="color:#009900">"group1"</span>)
                <span style="color:#009900">.build</span>()<span style="color:#880000">;</span></code></span>

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

  • 关于CronTrigger”熄火”的指令

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

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

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

这里列举很多最常用的Cron表达式例子,拿来即用,使用时注意区别:

<span style="color:#000000"><code>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执行</code></span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值