Quartz定时任务学习笔记
文章目录
1 quartz概念
quartz就是基于Java实现的任务调度框架,用于执行你想要执行的任何任务。
定时任务,定时的执行任务。
2 quartz运行环境
1.quartz可以在应用程序服务器内被实例化,并且参与事务
2.quartz可以运行嵌入在另一个独立式应用程序
3 quartz设计模式
1.Builder模式
2.Factory模式
3.组件模式(任务组件job,触发器组件trigger,调度组件scheduler)
4.链式编程
4 quartz学习的核心概念
3个组件:
任务job:Job就是你想要实现的任务类,每一个Job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法
触发器trigger:trigger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,
Trigger将会设置3点进行执行该任务Trigger主要包含SimpleTrigger和CronTrigger两种。
调度scheduler:scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job.
5 quartz的体系结构
6 quartz的几个常用API
scheduler 思该丢的
job 工作任务
JobDetail 实例
JobDataMap 数据对象
Trigger 触发器
TriggerBuilder 触发器创建器
JobBuilder 声明一个任务实例
JobListener,TriggerListener,SchedulerListener 监听器, 用于对组件的监听
7 quartz的使用
7.1 准备工作
7.2 引入quartz包
<!--quartz核心包-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<!--工具-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
7.3 入门案例
7.4 Job和JobDetail介绍
Job:工作任务的接口,任务类需要实现execute方法,类似于JDK的timeTask的run方法
在里面编写任务执行的业务逻辑
Job实例在quartz中的生命周期,每次调度器执行job时,它在调用extcute方法前会创建一个新的job实例,
当调度完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收;
JobDetail:JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定job
实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
JobDetail重要属性:name、group、jobClass、jobDataMap
jobDetail.getKey().getName(); //job名称
jobDetail.getKey().getGroup(); //job组名
jobDetail.getJobClass().getName(); //job任务类
7.5 JobExecutionContext介绍
。当scheduler调用一个job,就会将hjobExecutionContext传递给Job的execute()方法;
。Job能通过jobExecutionContext对象访问到quartz运行时候的环境以及job本身的明细数据;
7.6 JobDataMap介绍
1.使用Map获取
在进行任务调度时,jobDataMap存储在JobExecutionContext中,非常方便获取;
7.7 有状态的Job和无状态的Job
@PersistJobDataAfterExecution注解的使用
有状态的job可以理解为多次job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,
而默认的无状态job每次调用时都会创建一个新的jobDataMap.
1.修改HelloSchedulerDemo.java,添加usingJobData(“count”,0),表示计数器
JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentily("job1","group1") //定义该实例唯一标识
.usingJobData("message","打印日志")
.usingJobData("count",0)
.build();
2.修改HelloJob.java
添加countd setting和getting方法
private int count;
public void setCount(int count){
this.count = count;
}
HelloJob类没有添加@PersistJobDataAfterExecution注解,每次调用时都会创建一个新的jobDataMap,不会累加;
HelloJob类添加@PersistJobDataAfterExecution注解,多次job调用期间可以持有一些状态信息,即可以实现count的累加。
7.8 Trigger介绍
触发器
7.9 SimpleTrigger触发器
simpleTrigger对于设置和使用是最为简单的一种quertzTrigger;
它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行n次的job所设计的,
案例一:表示在一个指定的时间段内,执行一次作业任务;
案例二:在指定的时间间隔内多次执行作业任务
案例三:指定任务结束时间
需要注意的要点:
。SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔
。重复次数属性的值可以为0、正整数、或常量SimpleTrigger.REPEAT_INDEFINITELY
。重复的时间间隔属性值必须为0、或长整型的正整数,以毫秒作为时间单位,当重复的时间间隔为0时,
意味着与Trigger同时出发执行。
。如果有指定结束时间属性值,则结束时间属性值优先于重复次数属性,这样的好处在于:
当我们需要创建一个每间隔10秒钟触发一次直到指定的结束时间的Trigger,而无需去计算
从开始到结束所重复的次数,我们只需简单的指定结束时间和REPEAT_INDEFINITELY作为重复次数的属性值即可。
7.10 CronTrigger触发器
如果你需要像日历那样按日程来触发任务,而不是像SimpleTrigger那样每隔特定的间隔时间触发,
CronTrigger通常比SimpleTrigger更有用,因为它是基于日历的作业调度器。
使用CronTrigger,你可以指定比如"每个周五中午",或者"每个工作日9:30"或者从每个周一、周三、周五的上午9:00
到上午10:00之间每隔五分钟"这样日程安排来触发。甚至,像SimpleTrigger一样,CronTrigger也有一个startTime
以指定日程什么时候开始,也有一个(可选)endTime以指定何时日程不再继续。
1.cron Expression----cron表达式
cron表达式被用来配置cronTrigger实例,cron表达式是一个由7个子表达式组成的字符串,每个子表达式都描述了
一个单独的日程细节。这些子表达式用空格分隔,分别表示:
表示式 = 秒 分 时 日 月 周
1.seconds 秒
2.minutes 分s
3.hours 小时
4.day-of-month 月中的天 =日
5.month 月
6.day-of-week 周中的天 =周几
7.year 年(可选)
取值:
字段 运行值 特殊字符
秒 0-59 , - * /
分 0-59 , - * /
小时 0-23 , - * /
日 1-31 , - * / ?
月 1-12 , - * /
周 1-7 sun-sat , - * / ?
年 不填写 , - * /
, 指定多个值 MON,WED,FRI 周一、周三、周五
- 表示区间 10-12 表示10,11,12都会触发
* "每个" 日中的*表示一个月的每一天都会触发
? 在日和周中使用互斥 不设置这个字段的值 比如每月15日 不能保证都是周二,所有周就应该?
/ 表示增量 分中的0/15 每隔15分钟触发一次
练习:
"0 0 10,14,16 * * ?" ---每天的10点 14点 16点触发
"0 0/30 9-17 * * ?" ---朝九晚五时间内每半小时,从0分钟开始每隔30分钟触发一次
"0 0 12 ? * WED" ---每周三12点触发
"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 0-5 14 * * ?" ---每天下午2点到2:05期间的每1分钟触发
"0 10,44 14 * ? 3 WED" ---每年2月的2点10分和2:44触发
"0 15 10 ? * MON-FRI" ---周一到周五的10:15分触发
"0 15 10 15 * ?" ---每月15日10:15分触发
7.11 配置SchedulerFactory
quartz以模块方式架构,因此,要使它运行,几个组件必须很好的咬合在一起。幸运的是,
已经有了一些现存的助手可以完成这些工作。
所有的scheduler实例都是由schedulerFactory创建。
quartz的三个核心概念:调度器,任务,触发器
大家都知道,一个作业,比较重要的三个要素就是scheduler,jobDetail,trigger;
而Trigger对于job而言就好比一个驱动器,没有触发器来定时驱动作业,作业就无法运行,
对于job而言,一个job可以对应多个trigger,但对于trigger而言,一个trigger只能对应一个job,
所以,一个trigger只能指派给一个job,如果你需要一个更复杂的触发计划,你可以创建多个
trigger并指派给同一个job。
quartz的创建方式:
(1)stdchedulerFactory:
quartz默认的schedulerFactory
。使用一组参数(java.util.properties)来创建和初始化quartz调度器
。配置参数一般存储在quartz.properties文件中
。调用getScheduler方法就就能创建和初始化调度器对象
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
启动任务调度:
scheduler.start();
任务调度挂起,暂停操作:
scheduler.standby();
关闭调度任务:关闭后不能重新启动
scheduler.shutdown();
7.12 quartz.properties
我们也可以在项目的资源目下添加quartz.properties文件,去覆盖底层的配置文件
组成部分:
。调度器属性
org.quartz.scheduler.instanceName
。线程池属性
threadCount最好不要超过100
通过Properties设置工厂属性的缺点在于硬代码,假如需要修改例子中的线程数量,
将不得不修改代码,然后重新编译。我们这里不推荐使用。
8 quartz监听器
8.1 概念
quartz的监听器用于当任务调度中你所关注的事件发生时,能够及时获取这一事件的通知。
类似于任务执行过程中的邮件,短信类的提醒。quartz监听器主要有jobListener,triggerListener,
schedulerListener三种。顾名思义,分别表示任务,触发器,调度器对应的监听器。三者的使用方法类似,
在开始接受监听器之前,需要明确两个概念:全局监听器和局部监听器,二者的区别在于:
全局监听器能够接受到所有的job/trigger的事件通知;
而局部监听器只能接收到在上面注册的job或trigger的事件,不在其上面注册的job或trigger则不会进行监听。
8.2 JobListener任务的监听
任务调度过程中,与任务相关的事件包括:job开始要执行的提示;job执行完成的提示灯
添加到全局监听器:
scheduler.getListenerManager().addJobListener(new MyJobListener(),EverythingMatcher.allJObs));
添加到局部监听器 只有任务为job1时,MyJobListener监听器才会执行
scheduler.getListenerManager().addJobListener(new
MyJobListener(),KeyMatcher.keyEquals(JobKey.jobKey("job1","group1"))));
8.3 TriggerListener触发器的监听
创建并注册一个全局的trigger listener
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(),EverythingMatcher.allTriggers);
创建并注册一个局部的trigger listener
scheduler.getListenerManager().addTriggerListener(
new MyTriggerListener(),KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1","group1")));
8.4 SchedulerListener调度器的监听
创建调度器的监听:
scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
移除对应的调度器的监听:
scheduler.getListenerManager().removeSchedulerListener(new MySchedulerListener());
9 代码演示
9.1 quartz代码
9.1.1 HelloJob.java
Job类
package com.tangguanlin.quartz;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月13日 18时
*/
@PersistJobDataAfterExecution //多次调用job的时候,会对job进行持久化,保存一个数据的信息
public class HelloJob implements Job {
private int count;
public void setCount(int count) {
this.count = count;
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//输出当前时间
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);
//获取JobDetail的内容
JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
System.out.println("工作任务名称"+jobKey.getName()+":工作任务的组"+jobKey.getGroup());
System.out.println("任务类的名称"+jobExecutionContext.getJobDetail().getJobClass().getName());
//从JobDetail对象中获取jobDataMap的数据
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
String jobDetailMessage = jobDataMap.getString("message");
System.out.println("任务数据的参数值:"+jobDetailMessage);
//从Trigger对象中获取jobDataMap的数据
JobDataMap jobDataMap1 = jobExecutionContext.getTrigger().getJobDataMap();
String triggerMessage = jobDataMap1.getString("message");
System.out.println("触发器数据的参数值:"+triggerMessage);
//获取Trigger的内容
TriggerKey triggerKey = jobExecutionContext.getTrigger().getKey();
System.out.println("触发器名称"+triggerKey.getName()+":触发器的组"+triggerKey.getGroup());
//获取其他的内容
System.out.println("当前任务的执行时间:"+jobExecutionContext.getFireTime());
System.out.println("下一次任务的执行时间:"+jobExecutionContext.getNextFireTime());
//工作内容
System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);
++count;
System.out.println("count的数量:"+count);
//将count存放到jobDataMap中
jobExecutionContext.getJobDetail().getJobDataMap().put("count",count);
}
}
9.1.2 HelloSchedulerDemo.java
调度类
package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月13日 18时
*/
public class HelloSchedulerDemo {
public static void main(String[] args) throws SchedulerException {
//1.调度器(scheduler)从工厂中获取调度实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//2.任务实例(JobDetail)
//加载任务类,与HelloJob完成绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
.usingJobData("message","打印日志")
.usingJobData("count",0)
.build();
//3.触发器(Trigger)
SimpleTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
.usingJobData("message","simple触发器") //传递参数,名称message
.startNow() //马上启动触发器
.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
.build();
//4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
scheduler.scheduleJob(jobDetail,trigger);
//5.启动调度器
scheduler.start();
}
}
9.2 quartz Trigger代码
9.2.1 HelloJobTrigger.java
Job类
package com.tangguanlin.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Trigger;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月14日 02时
*/
public class HelloJobTrigger implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//输出当前时间
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);
//工作内容
System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);
Trigger trigger = jobExecutionContext.getTrigger();
System.out.println("jobkey的名称"+trigger.getJobKey().getName()+" jobkey的组名称:"+trigger.getJobKey().getGroup());
System.out.println("任务的开始时间:"+trigger.getStartTime() +" 任务的结束时间:"+trigger.getEndTime());
}
}
9.2.2 HelloSchedulerDemoTrigger.java
调度类
package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月13日 18时
*/
public class HelloSchedulerDemoTrigger {
public static void main(String[] args) throws SchedulerException {
//1.调度器(scheduler)从工厂中获取调度实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//设置任务的开始时间
Date startDate = new Date();
//任务的爱是时间推迟3s
startDate.setTime(startDate.getTime()+3000);
//设置任务的结束时间
Date endDate = new Date();
//任务的结束时间推迟10秒(10秒后停止)
endDate.setTime(endDate.getTime()+10000);
//2.任务实例(JobDetail)
//加载任务类,与HelloJob完成绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJobTrigger.class)
.withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
.build();
//3.触发器(Trigger) .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
//.startNow() //马上启动触发器
.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //5秒后重复执行
.startAt(startDate) //设置任务的开始时间
.endAt(endDate) //设置任务的结束时间
.build();
//4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
scheduler.scheduleJob(jobDetail,trigger);
//5.启动调度器
scheduler.start();
}
}
9.3 quartz SimpleTrigger代码
9.3.1 HelloJobSimpleTrigger.java
Job类
package com.tangguanlin.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月14日 02时
*/
public class HelloJobSimpleTrigger implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//输出当前时间
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);
//工作内容
System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);
}
}
9.3.2 HelloSchedulerDemoSimpleTrigger.java
调度类
package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月13日 18时
*/
public class HelloSchedulerDemoSimpleTrigger {
public static void main(String[] args) throws SchedulerException {
//1.调度器(scheduler)从工厂中获取调度实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//设置任务的开始时间
Date startDate = new Date();
//任务的开始时间推迟3s
startDate.setTime(startDate.getTime()+3000);
//设置任务的结束时间
Date endDate = new Date();
//任务的结束时间推迟10秒
endDate.setTime(endDate.getTime()+10000);
//2.任务实例(JobDetail)
//加载任务类,与HelloJob完成绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJobSimpleTrigger.class)
.withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
.build();
//3.触发器(Trigger) .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
//.startNow() //马上启动触发器
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.repeatSecondlyForever(5) //5秒后重复执行
.withRepeatCount(3)) //只重复3次,默认值是0
.startAt(startDate) //设置任务的开始时间
.endAt(endDate) //设置任务的结束时间
.build();
//4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
scheduler.scheduleJob(jobDetail,trigger);
//5.启动调度器
scheduler.start();
}
}
9.4 quartz CronTrigger代码
9.4.1 HelloJobCronTrigger.java
Job类
package com.tangguanlin.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月14日 02时
*/
public class HelloJobCronTrigger implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//输出当前时间
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);
//工作内容
System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);
}
}
9.4.2 HelloSchedulerDemoCronTrigger.java
调度类
package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
* 说明:
* 作者:汤观林
* 日期:2021年06月13日 18时
*/
public class HelloSchedulerDemoCronTrigger {
public static void main(String[] args) throws SchedulerException {
//1.调度器(scheduler)从工厂中获取调度实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//设置任务的开始时间
Date startDate = new Date();
//任务的开始时间推迟3s
startDate.setTime(startDate.getTime()+3000);
//设置任务的结束时间
Date endDate = new Date();
//任务的结束时间推迟10秒
endDate.setTime(endDate.getTime()+10000);
//2.任务实例(JobDetail)
//加载任务类,与HelloJob完成绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJobCronTrigger.class)
.withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
.build();
//3.触发器(Trigger) .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
.startNow() //马上启动触发器
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * 14 6 ?"))//日历
//.startAt(startDate) //设置任务的开始时间
//.endAt(endDate) //设置任务的结束时间
.build();
//4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
scheduler.scheduleJob(jobDetail,trigger);
//5.启动调度器
scheduler.start();
}
}
10 定时任务表达式
网站:
https://cron.qqe2.com/
https://www.bejson.com/othertools/cron/
常用表达式例子
(1)0/2 * * * * ? 表示每2秒 执行任务
(1)0 0/2 * * * ? 表示每2分钟 执行任务
(1)0 0 2 1 * ? 表示在每月的1日的凌晨2点调整任务
(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
(6)0 0 12 ? * WED 表示每个星期三中午12点
(7)0 0 12 * * ? 每天中午12点触发
(8)0 15 10 ? * * 每天上午10:15触发
(9)0 15 10 * * ? 每天上午10:15触发
(10)0 15 10 * * ? 每天上午10:15触发
(11)0 15 10 * * ? 2005 2005年的每天上午10:15触发
(12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
(13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
(14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
(15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
(18)0 15 10 15 * ? 每月15日上午10:15触发
(19)0 15 10 L * ? 每月最后一日的上午10:15触发
(20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
(22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
点
(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
(6)0 0 12 ? * WED 表示每个星期三中午12点
(7)0 0 12 * * ? 每天中午12点触发
(8)0 15 10 ? * * 每天上午10:15触发
(9)0 15 10 * * ? 每天上午10:15触发
(10)0 15 10 * * ? 每天上午10:15触发
(11)0 15 10 * * ? 2005 2005年的每天上午10:15触发
(12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
(13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
(14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
(15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
(18)0 15 10 15 * ? 每月15日上午10:15触发
(19)0 15 10 L * ? 每月最后一日的上午10:15触发
(20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
(22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发