任务调度:根据时间,执行任务。
比如:
(1)比如生活中的闹钟,我们设置闹钟每天早上七点执行响铃操作。我们给这个闹钟设定了时间,并且也给它设置了要进行执行的具体任务。关于这样的业务我们就称之为任务调度。
(2)假如在一个电商项目中,当用户在选择商品加入订单车后,如果在两个小时内没有支付,那么就自动会被取消掉。关于这样的功能我们如何去解决呢?
解决方案:
每十分钟扫描一下订单,来看一下订单库中有没有超过两个小时还没有支付的订单, 如果有的话就把订单给取消掉。这样的一个功能,它也有两个关键点,一个是每十分钟 执行一次。第二个关键点是具体要执行的任务是:对于那些超过两个小时还没有支付 的订单查询出来,然后进行一个取消的操作。那么具体如何实现呢?就要学习一下 Quartz框架。(当然还有很多其他解决方案,最好使用Redis)
官网: http://www.quartz-scheduler.org
核心概念:任务(Job)、触发器(Trigger)、调度器(Scheduler)
(1)任务:需要执行的具体工作。
(2)触发器:在特定的时间触发任务的执行。
(3)调度器:任务的实际执行者,负责粘合任务和触发器。
(1)创建一个普通的Maven项目,包名com.quartz 项目名TestQuartz。
(2)将Quartz所需要的Maven依赖进行添加。
org.quartz-scheduler
quartz
1.8.6
任务:需要执行的具体工作。
package com.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class RemindJob implements Job {
//继承Job必须实现的方法
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//提醒服务类,封装提醒业务
System.out.println("我正在执行....");
}
}
上面是Job类中的业务代码,在业务代码编写完后,要具体如何去调用这个Job呢?这就需要创建JobDetail实例对象。
//1、创建Job任务, 第一个参数是Job的名字, 第二个参数是Job的所属分组 第三个是具体Job的class
JobDetail job = new JobDetail("myJob", "A", RemindJob.class);
触发器:在特定的时间触发任务的执行。
SimpleTrigger是Trigger的子类。
(1)调度器:任务的实际执行者,负责粘合任务和触发器。
(2)通过JobDetail创建一个任务实例。
(3)使用SimpleTrigger创建一个触发器。
(4)创建一个调度器。
package com.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
public class TestQuartz {
public static void main(String[] args) throws SchedulerException, InterruptedException {
//1、创建Job任务, 第一个参数是Job的名字, 第二个参数是Job的所属分组 第三个是具体Job的class
JobDetail job = new JobDetail("myJob", "A", RemindJob.class);
//2、创建触发器Trigger。 REPEAT_INDEFINITELY 表示无限期重复. 重复间隔时间为3秒
SimpleTrigger simTrig = new SimpleTrigger("trigRemindJob", SimpleTrigger.REPEAT_INDEFINITELY, 3000);
//设置触发器在当前时间的下一秒开始。
simTrig.setStartTime(new Date(System.currentTimeMillis() + 1000));
//3、创建调度器
//3.1 创建scheduler工厂SchedulerFactory的实例对象
SchedulerFactory factory = new StdSchedulerFactory();
//3.2 通过scheduler工厂对象获取调度器
Scheduler scheduler = factory.getScheduler();
//4、将任务与触发器进行粘合
scheduler.scheduleJob(job, simTrig);
//5、启动调度器。
scheduler.start();
Thread.sleep(2000); //休眠2秒
//6、停止调度器
scheduler.shutdown();
}
}
注释掉代码中的(6、停止调度器)启动的话就会一直执行
//6、停止调度器
//scheduler.shutdown();
应用场景:
SimpleTrigger : 固定时间间隔的调度任务(例如:每2小时执行1次任务)
CronTrigger : 指定时间点的调度任务(例如:每天早晨7:00执行1次)
使用方式:
SimpleTrigger :通过设置触发器的属性:开始时间、结束时间、重复次数、重复间隔等。
CronTrigger : 通过定义Cron表达式
创建CronTrigger实例的代码。
CronTrigger cronTrigger = new CronTrigger(“myTrigger”,”group”,”* 35 15 ? * * ”);
测试代码如下所示
package com.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.ParseException;
public class TestQuartz {
public static void main(String[] args) throws SchedulerException, InterruptedException, ParseException {
//1、创建Job任务, 第一个参数是Job的名字, 第二个参数是Job的所属分组 第三个是具体Job的class
JobDetail job = new JobDetail("myJob", "A", RemindJob.class);
//2、创建CronTrigger实例对象,每天的12点42分执行JOB任务。
CronTrigger cronTrigger = new CronTrigger("myCronTrigger", "B", "0 42 12 ? * * ");
//3、创建调度器
//3.1 创建scheduler工厂SchedulerFactory的实例对象
SchedulerFactory factory = new StdSchedulerFactory();
//3.2 通过scheduler工厂对象获取调度器
Scheduler scheduler = factory.getScheduler();
//4、将任务与触发器进行粘合
scheduler.scheduleJob(job, cronTrigger);
//5、启动调度器。
scheduler.start();
Thread.sleep(2000000); //休眠2秒
//6、停止调度器
scheduler.shutdown();
}
}
位置 | 字段含义 | 范围 | 允许的特殊字符 |
---|---|---|---|
1 | 秒 | 0~59 | * / |
2 | 分钟 | 0~59 | * / |
3 | 小时 | 0~23 | * / |
4 | 月份中的哪一天 | 1~31 | * / ? L |
5 | 月份 | 112或JANDES | * / |
6 | 星期几 | 1~7或SUN-SAT | * / ? L # |
7 | 年份 | 1970~2099 | * / |
简写:秒 分 时 日 月 周 年。
测试关键代码
CronTrigger cronTrigger = new CronTrigger("myCronTrigger","B","0 54 10 * * ? ");
"":表示每一个值,它可以用于所有字段。
“?”:该字符仅用于”月份中的哪一天”字段和”星期几”字段,表示不指定值。注:这两个字段不能同时使用号或?号。 日、周字段
“-”:中划线,表示一个范围。
下面0-10表示0秒到10秒之间。
CronTrigger cronTrigger = new CronTrigger("myCronTrigger","B","0-10 54 10 * * ? ");
“,”:使用逗号间隔的数据,表示一个列表。
下面55,57,59 代表55秒、57秒、59秒的时候执行Job任务。
CronTrigger cronTrigger = new CronTrigger("myCronTrigger","B","55,57,59 54 10 * * ? ");
“/”:通常表示为x/y,x为起始值,y表示值的增量。
下面0/10,指从0秒开始,之后每10秒执行一次。
CronTrigger cronTrigger = new CronTrigger("myCronTrigger","B","0/10 54 10 * * ? ");
表达式 | 表达式作用 |
---|---|
0/10 * * * * ? | 每10秒执行一次 |
0/30 * * * * ? | 每30秒执行一次 |
0 0 0/2 * * ? | 每隔2个小时触发 |
0 0 0/4 * * ? | 每隔4个小时触发 |
0 0 12 * * ? | 每天中午12点触发 |
0 0 3 * * ? | 每天下午3点执行 |
0 0 1 1 * ? | 每月的一号1点执行一次 |
0 0 1 1 1 ? | 每年的一月一号的的1点执行一次 |
难的我也不会 给几个生成cron表达式网址吧
http://cron.qqe2.com/
https://qqe2.com/cron/index
http://www.bejson.com/othertools/cron/