java cron4j表达式与使用简介
参考文章:cron4j表达式与使用简介
java调度器cron4j的使用
Java语言cron4j轻量调度框架
官网
1.简介
cron4j是一个轻量级的Java任务调度工具。
cron4j is Free Software and it is licensed under LGPL (you will find a copy of the license bundled into the downloadable software distribution).具体见:官网介绍
2.规则介绍
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 等等)
3.使用介绍
3.1 引入Jar包
<dependency>
<groupId>it.sauronsoftware.cron4j</groupId>
<artifactId>cron4j</artifactId>
<version>2.2.5</version>
</dependency>
3.2 线程调度
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();
}
}
3.3 进程调度
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();
}
}
4. 代码示例
import com.jiangge.utils.task.TaskRunner;
import it.sauronsoftware.cron4j.Scheduler;
import it.sauronsoftware.cron4j.Task;
import it.sauronsoftware.cron4j.TaskExecutionContext;
/**
* 定时任务,目前有两种框架,一个是corn4j,一个是quartz
* <p>
* 这里我们分别做下介绍
* <p>
* corn4j其本身不支持秒,可以通过修改其源文件重新打包来实现支持,其默认规则如下
* 分:从0到59
* 时:从0到23
* 天:从1到31,字母L可以表示月的最后一天
* 月:从1到12,可以别名:"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov" and "dec"
* 周:从 0 到 6,0 表示周日,6 表示周六,可以使用别名: "sun", "mon", "tue", "wed", "thu", "fri" and "sat"
* <p>
* 数字 n:表示一个具体的时间点,例如 5 * * * * 表示 5 分这个时间点时执行
* 逗号 , :表示指定多个数值,例如 3,5 * * * * 表示 3 和 5 分这两个时间点执行
* 减号 -:表示范围,例如 1-3 * * * * 表示 1 分、2 分再到 3 分这三个时间点执行
* 星号 *:表示每一个时间点,例如 * * * * * 表示每分钟执行
* 除号 /:表示指定一个值的增加幅度。例如 * /5表示每隔5分钟执行一次(序列:0:00, 0:05, 0:10, 0:15 等等)。
* 再例如3-18/5 * * * * 是指在从3到18分钟值这个范围之中每隔5分钟执行一次(序列:0:03, 0:08, 0:13, 0:18, 1:03, 1:08 等等)。
*/
public class TimerTask {
public static void main(String[] args) {
/*MyTask myTask = new MyTask();
System.out.println("start");
taskRunner(myTask);
System.out.println("next start");
MyTaskrun myTaskrun = new MyTaskrun();
taskRunner(myTaskrun);*/
setTask();
}
public static void setTask() {
// 创建一个 Scheduler 实例.执行多任务
Scheduler s = new Scheduler();
s.schedule("/1 * * * *", new MyTaskRun());
s.schedule("/1 * * * *", new MyTask());
s.start();
try {
Thread.sleep(1000L * 60L * 1L);
} catch (InterruptedException e) {
System.out.println(e);
}
// Stops the scheduler.
//s.stop();
}
//通过使用实现接口的方式,定时执行任务
static class MyTaskRun implements Runnable {
public void run() {
System.out.println("123");
}
}
//通过继承Task的方式,定时执行任务
static class MyTask extends Task {
@Override
public void execute(TaskExecutionContext arg0) throws RuntimeException {
System.out.println("456");
}
}
public static void taskRunner(Object task) {
// 创建一个 Scheduler 实例.
Scheduler s = new Scheduler();
if (task instanceof Runnable) {
System.out.println("Runnable");
s.schedule("*/1 * * * *", (Runnable) task);
} else if (task instanceof Task) {
System.out.println("task");
s.schedule("*/1 * * * *", (Task) task);
}
// 自身调度执行一个任务
// s.schedule("*/1 * * * *", new Runnable()
// {
// public void run()
// {
// System.out.println("自我调用");
// }
// });
s.schedule("*/1 * * * *", new MyTaskrun());
s.schedule("*/1 * * * *", new MyTask());
// Starts the scheduler.
s.start();
// Will run for 1 minutes.
try {
System.out.println("try");
Thread.sleep(1000L * 60L * 1L);
} catch (InterruptedException e) {
System.out.println(e);
}
// Stops the scheduler.
s.stop();
System.out.println("stop");
}
}
5. 常见错误
常见错误:cron4j在表达式中使用除号指定增加幅度时与linux稍有不同。例如在linux中表达式 10/3 * * * * 的含义是从第10分钟开始,每隔三分钟调度一次,而在cron4j中需要使用 10-59/3 * * * * 来表达。避免这个常见错误的技巧是:当需要使用除号指定增加幅度时,始终指定其范围。
基于上面的技巧,每隔2分钟调度一次的表达式为:0-59/2 * * * * 或者 */2 * * * * , 而不能是0/2 * * * *
以上规则不是JFinal创造,是linux通用的cron表达式规则**(注意不是quartz规则)**,如果开发者本身具有这方面的知识,用起来会得心应手。原始文档链接:[cron4j - Documentation and manual][]
两大疑问:第一个疑问是当某个任务调度抛出了异常,那么这个任务在下次被调度的时间点上还会不会被调度,答案是肯定的,不管什么时候出现异常,时间一到调度仍然会被执行。
第二个疑问是假如某个任务执行时间很长,如果这个任务上次调度后直到本次调度到来的时候还没执行完,那么本次调度是否还会进行,答案也是肯定的。
总结一句话就是:每次调度都是独立的,上次调度是否抛出异常、是否执行完,都与本次调度无关。
**特别提醒:**Cron4jPlugin的cron表达式与linux一样只有5个部分,与quartz这个项目的7个部分不一样,但凡在网上搜索到的7部分cron表达式都不要试图应用在Cron4jPlugin之中。
还没有评论,来说两句吧...