扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
今天就跟大家聊聊有关如何正确的使用Cron4j表达式,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
我们提供的服务有:成都网站建设、网站设计、微信公众号开发、网站优化、网站认证、德城ssl等。为上千余家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的德城网站制作公司
cron4j是一个轻量级的Java任务调度工具。
引入Jar包:
it.sauronsoftware.cron4j cron4j 2.2.5
cron4j的cron表达式最多只允许5个部分,每个部分用空格分隔开,从左至右分别表示“分”、“时”、“天”、“月”、“周”,具体规则如下:
分:取值从 0 到 59 时:取值从 0 到 23 天:取值从 1 到 31,字母 L 可用于表示月的最后一天 月:取值从 1 到 12,可以用别名表示:jan、feb、mar、apr、may、jun、jul、aug、sep、oct、nov、dec 周:取值从 0 到 6,0表示周日,6表示周六,可以用别名表示:sun、mon、tue、wed、thu、fri、sat
以上5个部分的分、时、天、月、周又分别支持如下字符:
数字 n :表示一个具体的时间点,例如 5 * * * * 表示 5 分这个时间点时执行 逗号 , :表示指定多个数值,例如 3,5 * * * * 表示 3 和 5 分这两个时间点执行 减号 - :表示范围,例如 1-3 * * * * 表示 1 分、2 分再到 3 分这三个时间点执行 星号 * :表示每一个时间点,例如 * * * * * 表示每分钟执行 除号 / :表示指定一个值的增加幅度。例如 */5表示每隔5分钟执行一次(序列:0:00, 0:05, 0:10, 0:15 等等)
常见错误: cron4j在表达式中使用除号指定增加幅度时与linux稍有不同。例如在linux中表达式 10/3 * * * * 的含义是从第10分钟开始,每隔三分钟调度一次,而在cron4j中需要使用 10-59/3 * * * * 来表达。
Scheduler scheduler = new Scheduler(); //写法一:此种方式,控制台每分钟打印 scheduler.schedule("10-59/1 * * * *", () -> System.out.println("Every Minute Run.")); //写法二:此种方式,控制台不会有任何打印 //scheduler.schedule("10/1 * * * *", () -> System.out.println("Every Minute Run.")); scheduler.start(); try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { e.printStackTrace(); } scheduler.stop();
两大疑问: 第一个疑问是当某个任务调度抛出了异常,那么这个任务在下次被调度的时间点上还会不会被调度,答案是肯定的,不管什么时候出现异常,时间一到调度仍然会被执行。
Scheduler scheduler = new Scheduler(); scheduler.schedule("*/1 * * * *", () -> { System.out.println("Every Minute Run At: " + new Date()); throw new RuntimeException("任务调度抛出异常"); }); scheduler.start(); try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { e.printStackTrace(); } scheduler.stop();
打印结果如下:
Every Minute Run At: Wed Feb 13 10:09:00 CST 2019 java.lang.RuntimeException: 任务调度抛出异常 at com.tinytime.demo.cron4j.Demo2.lambda$main$0(Demo2.java:17) at it.sauronsoftware.cron4j.RunnableTask.execute(Unknown Source) at it.sauronsoftware.cron4j.TaskExecutor$Runner.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Every Minute Run At: Wed Feb 13 10:10:00 CST 2019 java.lang.RuntimeException: 任务调度抛出异常 at com.tinytime.demo.cron4j.Demo2.lambda$main$0(Demo2.java:17) at it.sauronsoftware.cron4j.RunnableTask.execute(Unknown Source) at it.sauronsoftware.cron4j.TaskExecutor$Runner.run(Unknown Source) at java.lang.Thread.run(Thread.java:748)
由此可见,即使上一次调度任务发生异常,下次任务到了时间仍然会被调度。
第二个疑问是假如某个任务执行时间很长,如果这个任务上次调度后直到本次调度到来的时候还没执行完,那么本次调度是否还会进行,答案也是肯定的。
Scheduler scheduler = new Scheduler(); scheduler.schedule("*/1 * * * *", () -> { System.out.println("开始调度任务...... At: " + new Date()); try { //等待两分钟 Thread.sleep(1000L * 60L * 2L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Every Minute Run At: " + new Date()); }); scheduler.start(); try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { e.printStackTrace(); } scheduler.stop();
打印结果如下:
开始调度任务...... At: Wed Feb 13 10:22:00 CST 2019 开始调度任务...... At: Wed Feb 13 10:23:00 CST 2019 开始调度任务...... At: Wed Feb 13 10:24:00 CST 2019 Every Minute Run At: Wed Feb 13 10:24:00 CST 2019 开始调度任务...... At: Wed Feb 13 10:25:00 CST 2019 Every Minute Run At: Wed Feb 13 10:25:00 CST 2019
由此可见,即使上一次调度任务没有执行完成,下次任务到了时间仍然会被调度。
总结:每次调度都是独立的,上次调度是否抛出异常、是否执行完,都与本次调度无关。
线程调度:
public class Quickstart { public static void main(String[] args) { Scheduler scheduler = new Scheduler(); scheduler.schedule("* * * * *", new Runnable() { @Override public void run() { System.out.println("Every Minute Run."); } }); scheduler.start(); try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { e.printStackTrace(); } scheduler.stop(); } }
系统进程调度:
public class ProcessJob { public static void main(String[] args) { ProcessTask task = new ProcessTask("C:\\Windows\\System32\\notepad.exe"); Scheduler scheduler = new Scheduler(); scheduler.schedule("* * * * *", task); scheduler.start(); } }
看完上述内容,你们对如何正确的使用Cron4j表达式有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流