文章目录

  • 一、触发器`Trigger`种类
  • 二、触发器`Trigger`实例
    • 2.1. `Trigger`常用属性
      • 2.1.1. `TriggerKey`
      • 2.1.2. 开始和结束时间
      • 2.1.3. 优先级
      • 2.1.4. 过期策略
    • 2.2. 产生错失/补偿的原因
  • 三、`Cron`表达式
    • 3.1. 简述
    • 3.2. 结构
    • 3.3. 特殊字符含义
    • 3.4. 常用实例
    • 3.4. 对于`CronTrigger`触发器写法
      • 3.4.1. 主要写法
      • 3.4.2. 其他方式
  • 四、参考文章

一、触发器Trigger种类

从类的继承图上可以看出一共有四种:

触发器名称 作用
SimpleTrigger 指定从某一个时间开始,以一定的时间间隔(默认单位时毫秒)执行任务。但是没办法指定一个月执行一次(每个月时间间隔不一致)
CalendarIntervalTrigger 指定从摸一个时间开始,以一定的时间间隔执行任务,支持指定间隔单位有妙、分钟、小时、天、月、年和星期
DailyTimetervalTrigger 指定每天某一个时间间隔,以一定的时间间隔执行任务,并且支持指定星期
CronTrigger 适合于更复杂的任务,它支持类型于Linux Cron的语法,基本上包含了上面三个Trigger的绝大部分功能

二、触发器Trigger实例

2.1. Trigger常用属性

我们在TriggerBuilder中可以看到有如下的属性

public class TriggerBuilder<T extends Trigger> {private TriggerKey key;private String description;private Date startTime = new Date();private Date endTime;private int priority = Trigger.DEFAULT_PRIORITY;private String calendarName;private JobKey jobKey;private JobDataMap jobDataMap = new JobDataMap();private ScheduleBuilder<?> scheduleBuilder = null;private TriggerBuilder() {}
}
2.1.1. TriggerKey

通过最后源码发现,name 不能为null,否则抛异常,groupnull 时,使用默认值 DEFAULT

public Key(String name, String group) {if(name == null)throw new IllegalArgumentException("Name cannot be null.");this.name = name;if(group != null)this.group = group;elsethis.group = DEFAULT_GROUP;
}
2.1.2. 开始和结束时间

我们可以看到默认就是当前时间,意味立即执行。当然TriggerBuilder也提供了一个方法设置立即执行:

public TriggerBuilder<T> startNow() {this.startTime = new Date();return this;
}

也支持单独设置开始时间和结束时间:

public TriggerBuilder<T> startAt(Date triggerStartTime) {this.startTime = triggerStartTime;return this;
}public TriggerBuilder<T> endAt(Date triggerEndTime) {this.endTime = triggerEndTime;return this;
}
2.1.3. 优先级

如果 Trigger 很多,或者 Quartz 线程池的工作线程太少,Quartz 可能没有足够的资源同时触发所有的 Trigger,这种情况下可能希望控制哪些 Trigger 优先使用 Quartz 的工作线程。

默认优先级是 :public static final int DEFAULT_PRIORITY = 5;优先级越小优先级越高。对于同时触发的Trigger 才会比较优先级。

2.1.4. 过期策略

这个我们在TriggerBuilder中没有看到,但是在抽象触发器AbstractTrigger是有的,默认是:

private int misfireInstruction = MISFIRE_INSTRUCTION_SMART_POLICY;  // 忽略

这个策略是在Trigger 接口中定义的,而设置这个策略需要在不同的TriggerScheduleBuilder中设置

CronScheduleBuilder支持三种:

  • withMisfireHandlingInstructionIgnoreMisfires(): 忽略所有的超时状态,按照触发器的策略执行
  • withMisfireHandlingInstructionFireAndProceed(): 立刻执行一次,然后就按照正常的计划执行
  • withMisfireHandlingInstructionDoNothing(): 目前不执行,然后就按照正常的计划执行

SimpleScheduleBuilder支持五种:

  • withMisfireHandlingInstructionIgnoreMisfires():忽略策略
  • withMisfireHandlingInstructionFireNow():立即执行策略
  • withMisfireHandlingInstructionNextWithExistingCount()重新安排下一步,现有计数
  • withMisfireHandlingInstructionNextWithRemainingCount()重新安排下一个,剩余计数
  • withMisfireHandlingInstructionNowWithExistingCount()(默认)对现有的重新开始计数执行
  • withMisfireHandlingInstructionNowWithRemainingCount()重新安排,重复计数

2.2. 产生错失/补偿的原因

  • 系统因为某些原因被重启
  • Trigger 被暂停(suspend)的一段时间里,有些任务可能会被 misfire
  • 线程池中所有线程都被占用,导致任务无法被触发执行,造成 misfire
  • 有状态任务在下次触发时间到达时,上次执行还没有结束

三、Cron表达式

在线验证网站:https://cron.qqe2.com/

3.1. 简述

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或者7个域,每一个域代表一个含义,Cron有如下两种格式:

  • 秒(Seconds) 分钟(Minutes) 小时(Hours) 日期(DayofMonth) 月份(Month) 星期(DayofWeek) 年(Year)
  • 秒(Seconds) 分钟(Minutes) 小时(Hours) 日期(DayofMonth) 月份(Month) 星期(DayofWeek)

3.2. 结构

字段 范围值 允许的特殊字符 序号
秒(Seconds) 0-59的整数 , - * / 1
分(Minutes) 0-59的整数 , - * / 2
小时(Hours) 0-23的整数 , - * / 3
日期(DayofMonth) 1-31的整数(实际月天数为准) , - * ? / L W C 4
月份(Month) 1-12的整数 , - * / 5
周(DayofWeek) 1-7的整数 , - * ? / L C # 6
年(可选,留空)(Year) 1970-2099 , - * / 7

3.3. 特殊字符含义

  • *(星花):表示匹配该域的任何值。例如在Minutes域使用*,即表示每分钟都会触发事件。
  • ?(问号): 只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。例如:月份中的日期和星期中的日期这两个元素时互斥的一起应该通过设置一个问号来表明不想设置那个字段。
  • -(短横杠):表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 。
  • /(斜杠): 表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次。
  • ,(逗号): 表示列出枚举值。例如:在Minutes域使用5,20,则意味在520分钟的时候触发。
  • L : 表示最后,只能出现在DayofWeekDayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
  • W : 表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。
  • LW : 这两个字符可以连用,表达在某个月最后一个工作日,即最后一个星期五。
  • # : 用于确定每个月的第几个星期几,只能出现在DayofMonth域。

3.4. 常用实例

表达式 含义
0 0 12 * * ? 每天中午12点触发
0 30 12 ?* * 每天中午12点半触发
0 * 12 * * ? 在每天下午12:00到12:59之间每一分钟触发一次
0 0/10 12 * * ? 在12:00到12:59之间每10分钟触发一次
0 0/5 10,19 * * ? 在10:00-10:59和19:00-19:59之间每5分钟触发一次
0 0-30 10 * * ? 在10:00-10:30之间每一分钟触发一次
0 10,20,30 12 * * ? 每天12点的10分、20分、30分的时候触发一次
0 12,24 12 ? 3 WED 每年三月的星期三12:12和12:24触发
0 10 12 15 * ? 每月15号12:10触发一次
0 20 12 L * ? 每月最后一天的12:20触发
0 20 12 ?* 6L 每个月最后一个星期五12:20触发
0 20 12 ? * 6#3 每月的第三个星期五12:20触发

3.4. 对于CronTrigger触发器写法

3.4.1. 主要写法

每两秒钟触发一次

Trigger trigger = triggerBuilder.withIdentity("trigger-1", "group-1").startNow().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();
3.4.2. 其他方式

另外CronScheduleBuilder还提供了一些封装的方法,例如dailyAtHourAndMinuteatHourAndMinuteOnGivenDaysOfWeekweeklyOnDayAndHourAndMinute。下面看一下其中dailyAtHourAndMinute的使用:

Trigger trigger = triggerBuilder.withIdentity("trigger-1", "group-1").startNow().withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(12, 20)).build();

这种相当于时对上面cron表单式的封装,看一下源码就知道了:

public static CronScheduleBuilder dailyAtHourAndMinute(int hour, int minute) {DateBuilder.validateHour(hour);DateBuilder.validateMinute(minute);// 相当于每天某小时某分钟执行String cronExpression = String.format("0 %d %d ? * *", minute, hour);return cronScheduleNoParseException(cronExpression);
}

其他两种也一样,就不一一赘述。

四、参考文章

https://blog.csdn.net/wangmx1993328/article/details/105309522

https://blog.csdn.net/zhanglong_4444/article/details/104322354

Java定时任务Quartz之触发器Trigger(二)相关推荐

  1. java 定时任务插件_详解Spring整合Quartz实现动态定时任务

    最近项目中需要用到定时任务的功能,虽然spring 也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之后,决定整合更为专业的Quartz来实现定时任务功能. 普通定时任务 首先 ...

  2. Springboot2 Quartz实现JAVA定时任务的动态配置

    动态配置Quartz.没接触过定时任务的同学可以先看下此篇:JAVA定时任务实现的几种方式 文章目录 一.需求背景 1. 问题现象 2. 问题分析 3. 解决方案 二.需求背景 2.1. maven依 ...

  3. Spring Boot 整合 Quartz 实现 Java 定时任务的动态配置

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 首先说下这次主题,动态配置.没接触过定时任务的同学可以先看 ...

  4. 墨客网java_墨客网-知识拆解+经典定时任务案例 精讲Java定时任务框架Elastic-Job和Quartz...

    课程介绍 精讲Elastic-job + Quartz实现企业级定时任务 掌握分布式集群方式的定时任务框架,可以弥补企业中常用的单点任务的缺点,以更高的性能更好的稳定性处理分布式定时任务服务:本课程带 ...

  5. Java定时任务的解决方案(Quartz等)

    ① JDK定时器:Timer 理论基础:时间轮算法 链表或者数组实现时间轮:while-true-sleep 遍历数组,每个下标放置一个链表,链表节点放置任务,遍历到了就取出执行 缺陷:假设数组长度1 ...

  6. Quartz.Net进阶之二:关于触发器的更多信息

    Quartz.Net进阶之二:关于触发器的更多信息 原文:Quartz.Net进阶之二:关于触发器的更多信息 与作业一样,触发器相对容易使用,但是在您可以充分利用Quartz.NET之前,确实需要了解 ...

  7. java 定时任务实现方式

    一.JDK自带定时任务 1.Timer java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行,但 ...

  8. Java定时任务技术分析

    <从零打造项目>系列文章 工具 比MyBatis Generator更强大的代码生成器 ORM框架选型 SpringBoot项目基础设施搭建 SpringBoot集成Mybatis项目实操 ...

  9. 定时任务Quartz的基本使用

    一.Quartz介绍 在很多情况下任务并非需要立即执行,而是需要往后或定期执行,这不可能人工去操作,所以定时任务就出现了 使用定时任务的情况: 每周末凌晨备份数据 触发条件 5 分钟后发送邮件通知 3 ...

最新文章

  1. adb 提示adb server version(31) doesn't match this client(40) 解决办法
  2. 开源阿牛图像处理实验室
  3. ACCESS中如何比较日期和时间,使用DateDiff函数
  4. 清华大学计算机系保送,2018年北大、清华五大学科竞赛集训队保送生争夺战结果...
  5. 两个音轨合并_两个双音轨mkv视频合并保持原双音轨不变 MKV怎么合并视频,合并之后仍保留MKV的双音轨...
  6. ubuntu server 9.04下配置ftp服务和可读写samba服务
  7. python获取当前路径和上一层路径_python获取当前路径和上一级路径
  8. Wi-Fi模块与蓝牙模块有何区别?
  9. Windows下使用python库 curses遇到错误消息的解决方案 1
  10. iOS $99 刀 开发者证书的申请步骤
  11. 352计算机调剂,今年考研金融专业352分能调剂吗?有机会调剂到哪些学校?
  12. Repeater——数据库控件学习
  13. BZOJ-1069 [SCOI2007]最大土地面积
  14. 编译的html帮助文件(.chm)打不开,chm文件无法打开怎么办
  15. uint 数据类型理解
  16. 给神经网络加入先验知识!
  17. 大型网站技术架构-读后感
  18. [转载]前端代码规范 及 最佳实践
  19. 周明:NLP进步将如何改变搜索体验
  20. 什么是restful?怎样用通俗的语言解释restful?

热门文章

  1. ros借助讯飞sdk实现问答机器人解决讯飞语音sdk11212erro
  2. 中年技术男创业失败经历
  3. CPU相关概念:物理cpu数、核数、逻辑cpu数,12核20线程实例分析
  4. Vue 项目运行完成后自动打开浏览器【多种方法】
  5. PHP项目上传到华为云服务器,php项目上传到云服务器
  6. python 定时器
  7. 艾永亮:当产品遇到超级产品战略会发生什么?
  8. javascript-js实现多线程
  9. 命令行提示: DNS 服务器对区域没有权威
  10. C++ const 和 constexpr 的用法和区别