Quartz定时调度器

三大核心组件:
  • 调度器:Scheduler
  • 任务:JobDetail
  • 触发器:Trigger,包括SimpleTrigger和CronTrigger

JobDetail: 就是我们要做什么,要做什么任务,比如说我们是要发送邮件,发送消息还是干别的什么。这是定时任务的主体。需要实现一个job接口,重写其中的方法,在方法中书写我们要做的事。
job
Trigger: 有了要做的事,接下来就是要设置执行周期,Trigger就是用于设置要执行的周期的,比如每几秒执行一次job中的内容
Trigger
Scheduler: 有了要干的事以及执行的周期了之后,接下来还需要一个调度器Scheduler,将他两关联在一起,使任务(job)可以在指定周期(Trigger)中执行。
Scheduler

使用

1、导入依赖的jar包

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

2、新建一个能够打印任意内容的Job

public class PrintWordsJob implements Job{

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());
        System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));
    }
}

3、创建Schedule,执行任务:
SimpleScheduleBuilder方式:

public class MyScheduler {

    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 1、创建调度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        // 2、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容)
        JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
                                        .withIdentity("job1", "group1").build();
        // 3、构建Trigger实例,每隔1s执行一次
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
                .startNow()//立即生效
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(1)//每隔1s执行一次
                .repeatForever()).build();//一直执行

        //4、执行
        scheduler.scheduleJob(jobDetail, trigger);
        System.out.println("--------scheduler start ! ------------");
        scheduler.start();

        //睡眠
        TimeUnit.MINUTES.sleep(1);
        scheduler.shutdown();
        System.out.println("--------scheduler shutdown ! ------------");
    }
}

使用CronScheduleBuilder方式:

@Test
public void test1() throws SchedulerException, InterruptedException {
    //1、创建一个任务调度器Scheduler
    StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
    Scheduler scheduler = stdSchedulerFactory.getScheduler();
    //2、创建一个job
    JobBuilder emailJob = JobBuilder.newJob(SendEmail.class);
    //对其进行起名分组构建
    JobDetail jobDetail = emailJob.withIdentity("sendEmail", "group1").build();
    //3、构建Trigger实例,对其起名分组开始
    TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger().withIdentity("mytrigger", "group1").startNow();
    //设置周期   每三秒一次
    Trigger trigger = triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule("1/3 * * * * ?")).build();
    //4、使用调度器使jobDetail和trigger关联在一起
    scheduler.scheduleJob(jobDetail,trigger);


    System.out.println("--------scheduler start ! ------------");
    scheduler.start();
    //睡眠
    TimeUnit.MINUTES.sleep(1);
    scheduler.shutdown();
}
cron 表达式的格式(网上有代码生成器)

Quartz Cron 表达式支持到七个域 :

名称是否必须允许值特殊字符
0-59, - * /
0-59, - * /
0-23, - * /
1-31, - * ? / L W C
1-12 或 JAN-DEC, - * /
1-7 或 SUN-SAT, - * ? / L C #
空 或 1970-2099, - * /

域之间有空格分隔,例如:* * * ? * *       每秒钟一次
Cron表达式有几个特殊的字符,说明如下:

  • “ - ”:中划线,表示一个范围 1-10
  • “ , ”:使用逗号间隔的数据,表示一个列表 1,8,10
  • “ * ”:表示每一个值,它可以用于所有字段。例如:在小时字段表示每小时 *
  • “ ? ”:该字符仅用于“月份中的哪一天”字段和“星期几”字段,表示不指定值
  • “ / ”:通常表示为x/y,x为起始值,y表示值的增量。
  • “ L ”:表示最后一天,仅在日期和星期字段中使用
  • “ # ”:只能用于“星期几”字段,表示这个月的第几个周几。例如:“6#3”指这个月第三个周五

详讲:

  • ? 号只能用在日和周域上,但是不能在这两个域上同时使用。你可以认为 ? 字符是 “我并不关心在该域上是什么值。” 这不同于星号,星号是指示着该域上的每一个值。? 是说不为该域指定值。
    不能同时这两个域上指定值的理由是难以解释甚至是难以理解的。基本上,假定同时指定值的话,意义就会变得含混不清了:考虑一下,如果一个表达式在日域上有值11,同时在周域上指定了 WED。那么是要 trigger 仅在每个月的11号,且正好又是星期三那天被激发?还是在每个星期三的11号被激发呢?要去除这种不明确性的办法就是不能同时在这两个域上指定值。
    只要记住,假如你为这两域的其中一个指定了值,那就必须在另一个字值上放一个 ?。
    表达式样例:
    0 10,44 14 ? 3 WEB
    意义:在三月中的每个星期三的下午 2:10 和 下午 2:44 被触发。

  • , 逗号
    逗号 (,) 是用来在给某个域上指定一个值列表的。例如,使用值 0,15,30,45 在秒域上意味着每15秒触发一个 trigger。
    表达式样例:
    0 0,15,30,45 * * * ?
    意义:每刻钟触发一次 trigger。

  • / 斜杠
    斜杠 (/) 是用于时间表的递增的。我们刚刚用了逗号来表示每15分钟的递增,但是我们也能写成这样 0/15。
    表达式样例:
    0/15 0/30 * * * ?
    意义:在整点和半点时每15秒触发 trigger。

  • – 中划线
    中划线 (-) 用于指定一个范围。例如,在小时域上的 3-8 意味着 “3,4,5,6,7 和 8 点。” 域的值不允许回卷,所以像 50-10 这样的值是不允许的。
    表达式样例:
    0 45 3-8 ? * *
    意义:在上午的3点至上午的8点的45分时触发 trigger。

  • L 字母
    L 说明了某域上允许的最后一个值。它仅被日和周域支持。当用在日域上,表示的是在月域上指定的月份的最后一天。例如,当月域上指定了 JAN 时,在日域上的 L 会促使 trigger 在1月31号被触发。假如月域上是 SEP,那么 L 会预示着在9月30号触发。换句话说,就是不管指定了哪个月,都是在相应月份的时最后一天触发 trigger。
    表达式 0 0 8 L * ? 意义是在每个月最后一天的上午 8:00 触发 trigger。在月域上的 * 说明是 “每个月”。
    当 L 字母用于周域上,指示着周的最后一天,就是星期六 (或者数字7)。所以如果你需要在每个月的最后一个星期六下午的 11:59 触发 trigger,你可以用这样的表达式 0 59 23 ? * L。
    当使用于周域上,你可以用一个数字与 L 连起来表示月份的最后一个星期 X。例如,表达式 0 0 12 ? * 2L 说的是在每个月的最后一个星期一触发 trigger。
    不要让范围和列表值与 L 连用
    虽然你能用星期数(1-7)与 L 连用,但是不允许你用一个范围值和列表值与 L 连用。这会产生不可预知的结果。

  • W 字母
    W 字符代表着平日 (Mon-Fri),并且仅能用于日域中。它用来指定离指定日的最近的一个平日。大部分的商业处理都是基于工作周的,所以 W 字符可能是非常重要的。例如,日域中的 15W 意味着 “离该月15号的最近一个平日。” 假如15号是星期六,那么 trigger 会在14号(星期四)触发,因为距15号最近的是星期一,这个例子中也会是17号(译者Unmi注:不会在17号触发的,如果是15W,可能会是在14号(15号是星期六)或者15号(15号是星期天)触发,也就是只能出现在邻近的一天,如果15号当天为平日直接就会当日执行)。W 只能用在指定的日域为单天,不能是范围或列表值。

  • #井号
    #字符仅能用于周域中。它用于指定月份中的第几周的哪一天。例如,如果你指定周域的值为 6#3,它意思是某月的第三个周五 (6=星期五,#3意味着月份中的第三周)。另一个例子 2#1 意思是某月的第一个星期一 (2=星期一,#1意味着月份中的第一周)。注意,假如你指定 #5,然而月份中没有第 5 周,那么该月不会触发。

语法格式:

秒 分 时 天 月 星期 年

常用表达式例子

(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触发
(23)“0 0 12 * * ?” 每天中午12点触发
(24)“0 15 10 ? * " 每天上午10:15触发
(25)“0 15 10 * * ?” 每天上午10:15触发
(26)"0 15 10 * * ?
” 每天上午10:15触发
(27)“0 15 10 * * ?2005” 2005年的每天上午10:15触发
(28)“0 * 14 * * ?” 在每天下午2点到下午2:59期间的每1分钟触发
(29)“0 0/5 14 * *?” 在每天下午2点到下午2:55期间的每5分钟触发
(30)“0 0/5 14,18 * * ?” 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
(31)“0 0-5 14 * * ?” 在每天下午2点到下午2:05期间的每1分钟触发
(32)“0 10,44 14 ? 3WED” 每年三月的星期三的下午2:10和2:44触发
(33)“0 15 10 ? *MON-FRI” 周一至周五的上午10:15触发
(34)“0 15 10 15 * ?” 每月15日上午10:15触发
(35)“0 15 10 L * ?” 每月最后一日的上午10:15触发
(36)“0 15 10 ? *6L” 每月的最后一个星期五上午10:15触发
(37)“0 15 10 ? * 6L2002-2005” 2002年至2005年的每月的最后一个星期五上午10:15触发
(38)“0 15 10 ? *6#3” 每月的第三个星期五上午10:15触发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值