• 初识Quartz(三)


    本文将介绍CronTrigger的使用方法,CronTrigger相比 SimpleTrigger可以支持更复杂的作业计划。cron这一观念来自UNIX,在UNIX中,cron是一个运行于后台的守护程序,它负责所有基 于时间的时间。Unix cron守护进程每个一分钟被唤醒一次去检查叫做crontabs的配置文件,以此来决定是否有要执行的任务。个人觉得Quartz就是借鉴了它的名字和 相似的语法表达式,如果你之前接触过cron,那么理解本文将会很轻松。

    简单作业:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    package quartz_project.example3;
     
    import java.util.Date;
     
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.JobKey;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    /**
     * 需要在特定的日期或者时间启动,
     * 并且期望以一个可能的间隔时间重复执行 n 次的Job,配合CronTrigger的测试
     
     * @author caijw
     */
    public class SimpleJob implements Job {
         
        private static Logger _log = LoggerFactory.getLogger(SimpleJob.class);
     
        @Override
        public void execute(JobExecutionContext ctx) throws JobExecutionException {
            JobKey jobKey = ctx.getJobDetail().getKey();
            _log.info("SimpleJob says: " + jobKey + " executing at " new Date());
        }
     
    }

    初始运行环境:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Logger log = LoggerFactory.getLogger(CronTriggerExample.class);
     
    log.info("------- Initializing -------------------");
    // 获取一个调度器
    SchedulerFactory sf = new StdSchedulerFactory();
    Scheduler sched = sf.getScheduler();
     
    log.info("------- Initialization Complete --------");
     
    log.info("------- Scheduling Jobs ----------------");

    一、每20秒执行一次job1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    JobDetail job = newJob(SimpleJob.class)
        .withIdentity("job1""group1")
        .build();
     
    CronTrigger trigger = newTrigger()
        .withIdentity("trigger1""group1")
        .withSchedule(cronSchedule("0/20 * * * * ?"))
        .build();
     
    Date ft = sched.scheduleJob(job, trigger);
    log.info(job.getKey() + " has been scheduled to run at: " + ft
            " and repeat based on expression: "
            + trigger.getCronExpression());

        注意:trigger.getCronExpression(); //获取cron表达式

        cron表达式:0/20 * * * * ?

        执行效果:每隔20秒执行一次

    二、每隔一分钟,第15秒执行一次job2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    job = newJob(SimpleJob.class)
        .withIdentity("job2""group1")
        .build();
     
    trigger = newTrigger()
        .withIdentity("trigger2""group1")
        .withSchedule(cronSchedule("15 0/2 * * * ?"))
        .build();
     
    ft = sched.scheduleJob(job, trigger);
    log.info(job.getKey() + " has been scheduled to run at: " + ft
            " and repeat based on expression: "
            + trigger.getCronExpression());

        cron表达式:15 0/2 * * * ?

        执行效果类似于:1分15秒执行、3分15秒执行、5分15秒执行...以此类推

    三、在某一时间段内,每隔一分钟执行一次job3

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    job = newJob(SimpleJob.class)
        .withIdentity("job3""group1")
        .build();
     
    trigger = newTrigger()
        .withIdentity("trigger3""group1")
        .withSchedule(cronSchedule("0 0/2 8-17 * * ?"))
        .build();
     
    ft = sched.scheduleJob(job, trigger);
    log.info(job.getKey() + " has been scheduled to run at: " + ft
            " and repeat based on expression: "
            + trigger.getCronExpression());

        cron表达式:0 0/2 8-17 * * ?

        执行效果:每天的上午8点到下午5点,每隔2分钟的0秒执行一次job3

    四、指定某天某个时间点执行job4

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    job = newJob(SimpleJob.class)
        .withIdentity("job4""group1")
        .build();
     
    trigger = newTrigger()
        .withIdentity("trigger4""group1")
        .withSchedule(cronSchedule("0 0 10am 1,15 * ?"))
        .build();
     
    ft = sched.scheduleJob(job, trigger);
    log.info(job.getKey() + " has been scheduled to run at: " + ft
            " and repeat based on expression: "
            + trigger.getCronExpression());

        cron表达式:0 0 10am 1,15 * ?

        执行效果:每月的1号和15号,上午10点整执行一次job4

    五、指定在工作日(周一到周五)某个时间点执行job5

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    job = newJob(SimpleJob.class)
        .withIdentity("job5""group1")
        .build();
     
    trigger = newTrigger()
        .withIdentity("trigger5""group1")
        .withSchedule(cronSchedule("0,30 * * ? * MON-FRI"))
        .build();
     
    ft = sched.scheduleJob(job, trigger);
    log.info(job.getKey() + " has been scheduled to run at: " + ft
            " and repeat based on expression: "
            + trigger.getCronExpression());

        cron表达式:0,30 * * ? * MON-FRI

        执行效果:每个星期的周一到周五,每分钟的0秒和30秒执行一次job5

        同样,假如我们想让一个任务在周六和周日执行,cron表达式类似:0,30 * * ? * SAT,SUN

    六、执行任务

        上面的代码仅仅将任务添加到了调度器中,只有调度器启动后,才可以进行任务调度。

    1
    sched.start();

    七、Cron Expression格式

        之所以把这块放在最后,就是希望大家可以先从上面的例子直观的体会一下cron表达式究竟会带给我们什么样的执行效果。下面简单的介绍下它的使用语法:

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

    * 星号:表示该域上所有合法的值,如在月份上使用星号,意味这每个月都会触发这个trigger。

    ? 问号: 只能用在日和周这两个域上,但是不可以同时使用。这里比较难理解,但是你只需记住,如果你为这两个域中的其中一个指定了值,那么另外一个必须使用?。举个 例子:0 10 14 ? 3 WEB,意思就是在3月的每个星期三下午2:10触发一次,因为周域上已指定WEB,所以日域上就必须使用?。

    , 逗号:用来给某个域上指定一个值列表的。如在分域上使用0,15,30,45意味着每刻(15分钟)触发这个trigger。

    / 斜杠:表示时间表递增,如上面的例子可以写成:0/15,表示每隔15分钟触发trigger。

    - 中划线: 用于知道一个范围。如时域上使用:4-10,意味着凌晨4点到上午10点触发trigger。

    L字母: 指定某域上运行的最后一个值,仅支持日和周这两个域。当用在日域上,表示的是在月域上指定月份的最后一天(避免了月底31, 30, 28, 29这样的烦恼)。如果用在周域上,表示这个周的最后一天,即星期六。

    W字母:代表这平日(周一到周五),并且仅能用在日域中。它用来指定离指定日的最近的一个平日。例如:15W,假如某月的15号是星期六,那么该trigger将在14号触发,因为星期五(14号)比星期一(17号)更近。如果15号本身就是平日,那么就在当天执行。

    # 井号: 仅能用在周域中。它用于指定月份中的第几周的哪一天。例如,指定周域为6#3,它意味着某月的第三个周五(6=星期五,#3即月份中的第三周)。

    C字母指和calendar联系后计算过的值。例:在日域用“5C”指在这个月第5天或之后包括calendar的第一天;在周域用“1C”指在这周日或之后包括calendar的第一天。

  • 相关阅读:
    匈牙利算法demo
    linux/windows 文件共享--Samba环境搭建
    神经网络参数量和计算量计算
    C/C++ 开发中使用第三方库常见问题总结
    linux 如何更改docker的默认存储磁盘
    目录下文件递归查找
    c++ 项目开发技巧
    Finding Tiny faces 思想解析
    美女与硬币问题
    深度优先遍历解决连通域求解问题-python实现
  • 原文地址:https://www.cnblogs.com/kabi/p/5239815.html
Copyright © 2020-2023  润新知