Java定时任务调度工具详解(6)— Quartz 之 SimpleTrigger、CronTrigger、Cron表达式

时间:2022-01-13 21:24:46

六、SimpleTrigger

SimpleTrigger的作用

在一个指定时间段内执行一次作业任务或是在指定的时间间隔内多次执行作业任务

需要注意的点

重复次数可以为0,正整数或是SimpleTrigger.REPEAT_INDEFINITELY常量值
重复执行间隔必须为0或长整数
一旦被指定了endTime参数,那么它会覆盖重复次数参数的效果

代码演示

源码地址:https://gitee.com/liupeifeng3514/Timer-Quartz

HelloJob类改造

package helloquartz.four;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/** * SimpleTrigger 演示 */
public class HelloJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 打印当前的执行时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));

        System.out.println("Hello World!");
    }
}

HelloScheduler类改造

package helloquartz.four;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

/** * SimpleTrigger 演示 */
public class HelloScheduler {

    public static void main(String[] args) throws SchedulerException {
        // 打印当前的执行时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("--------Current Time Is : " + sf.format(date));

        // 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定
        JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class)
                .withIdentity("myjob", "jobgroup1")// 定义标识符
                .build();

        // 获取距离当前时间4秒钟之后的具体时间
        date.setTime(date.getTime() + 4000);
        // 获取距离当前时间6秒钟之后的具体时间
        Date endDate = new Date();
        endDate.setTime(endDate.getTime() + 6000);

        // 距离当前时间4秒钟后首次执行任务,之后每隔2秒钟重复执行一次任务
        // 直到距离当前时间6秒钟之后为止
        SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger","trigroup1")// 定义标识符
                .startAt(date)
                .endAt(endDate)
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()
                        .withIntervalInSeconds(2)
                        .withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY))
                .build();

        // 创建 Scheduler 实例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        scheduler.scheduleJob(jobDeatil, trigger);
        scheduler.start();
    }
}

执行结果:

--------Current Time Is : 2018-03-07 13:04:32
2018-03-07 13:04:33,008 [INFO ][main] Using default implementation for ThreadExecutor  (org.quartz.impl.StdSchedulerFactory:StdSchedulerFactory.java:1172) 
2018-03-07 13:04:33,012 [INFO ][main] Job execution threads will use class loader of thread: main  (org.quartz.simpl.SimpleThreadPool:SimpleThreadPool.java:268) 
2018-03-07 13:04:33,030 [INFO ][main] Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl  (org.quartz.core.SchedulerSignalerImpl:SchedulerSignalerImpl.java:61) 
2018-03-07 13:04:33,030 [INFO ][main] Quartz Scheduler v.2.2.3 created.  (org.quartz.core.QuartzScheduler:QuartzScheduler.java:240) 
2018-03-07 13:04:33,031 [INFO ][main] RAMJobStore initialized.  (org.quartz.simpl.RAMJobStore:RAMJobStore.java:155) 
2018-03-07 13:04:33,031 [INFO ][main] Scheduler meta-data: Quartz Scheduler (v2.2.3) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
  (org.quartz.core.QuartzScheduler:QuartzScheduler.java:305) 
2018-03-07 13:04:33,032 [INFO ][main] Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'  (org.quartz.impl.StdSchedulerFactory:StdSchedulerFactory.java:1327) 
2018-03-07 13:04:33,032 [INFO ][main] Quartz scheduler version: 2.2.3  (org.quartz.impl.StdSchedulerFactory:StdSchedulerFactory.java:1331) 
2018-03-07 13:04:33,033 [INFO ][main] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.  (org.quartz.core.QuartzScheduler:QuartzScheduler.java:575) 
--------Current Exec Time Is : 2018-03-07 13:04:36
--------Hello World!
--------Current Exec Time Is : 2018-03-07 13:04:38
--------Hello World!

七、CronTrigger

CronTrigger的作用

基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用

Cron表达式

用于配置CronTrigger实例
是由7个子表达式组成的字符串,描述了时间表的详细信息
格式:[秒][分][小时][日][月][周][年]

Cron表达式特殊字符意义对应表

字段 是否必填 允许值 允许的特殊字符
0~59 , - * /
0~59 , - * /
小时 0~23 , - * /
1~31 , - * ? / L W C
1~12 或者 JAN-DEC , - * /
1~7 或者 SUN-SAT , - * ? / L C #
empty,1970~2099 , - * /

特殊符号解释

特殊字符 含义
* 表示所有值。例如:在分的字段上设置“*”,表示每一分钟都会触发。
?                 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为“?”,具体设置为 0 0 0 10 * ?
- 表示区间。例如 在小时上设置 “10-12”,表示 10,11,12点都会触发。
表示指定多个值,例如在周字段上设置 “MON,WED,FRI”,表示周一,周三和周五触发
/ 用于递增触发。如在秒上面设置“5/15”,表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置’1/3’所示每月1号开始,每隔三天触发一次。
L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]),在周字段上表示星期六,相当于“7”或“SAT”。如果在“L”前加上数字,则表示该数据的最后一个。例如在周字段上设置“6L”这样的格式,则表示“本月最后一个星期五”
W 表示离指定日期的最近那个工作日(周一至周五)。例如在日字段上设置“15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发,如果15号是周未,则找最近的下周一(16号)触发。如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,“W”前只能设置具体的数字,不允许区间“-”)。’L’和 ‘W’可以一组合使用。如果在日字段上设置“LW”,则表示在本月的最后一个工作日触发
# 序号(表示每月的第几周星期几),例如在周字段上设置“6#3”表示在每月的第三个周星期六。注意如果指定“6#5”,正好第五周没有星期六,则不会触发该配置(用在母亲节和父亲节再合适不过了)周字段的设置,若使用英文字母是不区分大小写的MON与mon相同。

Cron表达式举例

表达式 含义
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)

Cron表达式小提示

L和W可以一组合使用
周字段英文字母不区分大小写即MON与mon相同
利用工具,在线生成