在项目中常常会想要这样的功能:
在客户把商品加入到购物车后,如果30分钟没支付该订单,那么该订单失效,或者在这个时候提醒客户进行支付
,这些需求的实现都来自于定时任务调度框架.
今天来学一个简单的
任务调度框架Quartz
Quartz:
是一个
定时任务调度框架
.比如你遇到这样的问题:
- 想在30分钟后,查看订单是否支付,未支付则取消订单
- 想在每月29号,信用卡自动还款
- …
- 想定时在某个时间,去做某件事(任务)
Quartz是要做定时任务的调度,设置好触发
时间规则
,以及相应任务(Job)
即可.
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartzartifactId>
<version>2.2.1version>
dependency>
实现接口Job
package per.leiyu;
import org.quartz.*;
/**
* @author 雷雨
* @date 2020/6/27 21:05
*/
/**
* 定义了一个Job任务
*/
public class MyJob01 implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("你好,我是定时任务");
//可以通过JobExecutionContext来获取任务的标识(name)和组别(group)
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobKey key = jobDetail.getKey();
System.out.println(key.getName());//任务标识
System.out.println(key.getGroup());//任务组别
}
}
package per.leiyu;
/**
* @author 雷雨
* @date 2020/6/27 21:06
*/
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.GregorianCalendar;
/**
* Quartz API
*/
public class HelloQuartz {
public static void main(String[] args) throws SchedulerException {
//1.定义一个调度器 Scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//2.定义一个触发器
//触发器中描述任务Job的触发规则
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).withRepeatCount(10))
.endAt(new GregorianCalendar(2020, 5, 27, 21, 25, 30).getTime())
.build();
//3,JobDetail
//注意jbo的名字和组别和触发器的名称和组别是隔离的,那么就可以同名
JobDetail jobDetail = JobBuilder.newJob(MyJob01.class).withIdentity("job1", "group1").build();
//4.将JobDetail和触发器添加到调度器中
scheduler.scheduleJob(jobDetail,trigger);
//5.启动 调度器开始工作
scheduler.start();
}
}
定时任务结果,为了方便观察在输出中加了时间戳 |
---|
可以添加Quartz的配置文件,设置Quartz的默认启动配置
#名为:quartz.properties ,放置在classpath下,如果没有此配置则按默认配置启动
# 指定调度器名称,非实现类
org.quarz.scheduler.instanceName = DefaultQuartzScheduler
#指定线程池实现类
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
#线程池线程数量
org.quartz.threadPool.threadCount=10
#优先级,默认5
org.quartz,threadPool.threadPriority= 5
#非持久化job
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
- Scheduler:调度器.所有的调度都是由它控制,是Quartz的大脑,所有任务和调度都由它管理
- Job:任务,想定时执行的事情(定义业务逻辑)
- JobDetail:基于Job,进一步包装.其中关联一个Job,并为Job指定更为详细的属性,比如标识等
- Trigger:触发器.可以指定给某个任务,指定任务的触发机制
以一定的时间间隔(单位是毫秒)执行的任务
- 指定起始和截止时间(时间段)
- 指定时间间隔,执行次数
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2)//每两秒执行一次
.withRepeatCount(10))//执行次数不超过10次
.endAt(new GregorianCalendar(2020, 5, 27, 21, 30, 30).getTime())
.build();
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2)//每两秒执行一次
.repeatForever())//不限制执行次数,由起始截止时间和间隔决定执行次数
.endAt(new GregorianCalendar(2020, 5, 27, 21, 30, 30).getTime())
.build();
适合于更复杂的任务,它支持类型于Linux Cron的语法(很强大)
- 执行Cron表达式即可
示例:
CronTrigger trigger1 = TriggerBuilder.newTrigger()
.withIdentity("trigger1","group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0/2 10-12 * * ?"))
.build();
表达式组成"秒 分 时 日 月 星期几 [年]",其中年是可选参数,一般不指定
- 注意日 ,月可以决定星期,因此如果日,月执行明确的话,星期用 ?表示
位置 | 时间域 | 允许值 | 特殊值 |
---|---|---|---|
1 | 秒 | 0-59 | ,-*/ |
2 | 分钟 | 0-59 | ,-*/ |
3 | 小时 | 0-23 | ,-*/ |
4 | 日期 | 1-31 | ,-*?/LW |
5 | 月份 | 1-12 | ,-*/ |
6 | 星期 | 1-7 | ,-*?/LW |
7 | 年份(可选) | ,-*/ |
表达式中可使用的符号的含义
符号 | 语义 |
---|---|
星号(*) | 可用在所有字段中,表示对应时间域的每一个时刻,例如在分钟字段中,表示的是"每分钟" |
问号(?) | 该字符只在日期和星期字段中使用,它通常指定为"不确定值" |
减号(-) | 表示一个范围,如在小时字段中使用"10-12",则表示从10点到12点,即10,11,12 |
逗号(,) | 表示一个列表值,如在星期字段中使用"MON,WEB,FRI",则表示星期一,星期二,星期三 |
斜杆(/) | x/y表示一个等步长序列,x为起始值,y为增量步长值.如在分钟字段中使用0/15,则表示的是0,15,30,45,分钟 |
井号(#) | 该字符只用在星期字段中,"4#2"表示的是第二个星期3,"5#4"表示的是第4个星期四 |
L | 该字符只能出现在日期和星期字段中,代表的是"Last"的意思,但它在两个字段中含义不同 |
如果L用在星期字段中,则表示星期6,等同于7 | |
L出现在星期字段中,而且在前面有一个数值x,则表示"这个月最后一个周x",例如:6L代表这个月最后一个周五 | |
L在日期字段中,表示这个月份的最后一天,如一月的31号 | |
W | 该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日 |
例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五,如果15号是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二;但必须注意关联的匹配日期不能跨月 | |
LW组合 | 在日期字段可以组合使用LW,它的意思是当月的最后一个工作日 |
我是雷雨,一个
普本科
的学生,主要专注于Java后端和大数据开发
如果这篇文章有帮助到你,希望你给我一个
大大的赞
如果有什么问题,希望你能留言
和我一起研究
,学习靠自觉,分享靠自愿
转载注明出处
https://blog.csdn.net/qq_40742223