Quartz任务调度定时器使用总结
一、前言
Quartz是一个完全由java编写的开源作业调度框架,说人话就是你可以创建一些任务,规定这些任务什么时候执行、执行几次等。本文记录项目过程中Quartz的常用方法。
官方下载地址 http://www.quartz-scheduler.org/downloads/
官网比较慢,可以在CSDN下载 https://download.csdn.net/download/leytton/10346005
经测试只需要引入quartz-2.2.3.jar、quartz-jobs-2.2.3.jar和slf4j-api-1.7.7.jar就行了
或者使用Maven:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
二、Quartz项目结构
参考https://www.cnblogs.com/drift-ice/p/3817269.html
0x01、定义一个任务(Job)
JobHelloQuartz.java
public class JobHelloQuartz implements Job {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail detail = context.getJobDetail();
String name = detail.getJobDataMap().getString("name");
System.out.println(detail.getKey()+" say hello to " + name + " at " + sdf.format(new Date()));
}
}
0x02调度任务
Test01.java
public class Test01 {
public static void main(String[] args) {
try {
// 创建scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 定义一个Trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("Trigger_HelloQuartz", "group1") // 定义name/group
// .startNow()//一旦加入scheduler,立即执行
.startAt(new Date(System.currentTimeMillis() + 5000))// 5秒后执行
.withSchedule(SimpleScheduleBuilder.simpleSchedule() // 使用SimpleTrigger
.withIntervalInSeconds(2) // 每隔2秒执行一次
.withRepeatCount(1))// 重复1次,共计2次
// .repeatForever()) //一直执行,奔腾到老不停歇
.build();
// 定义一个JobDetail
JobDetail job = JobBuilder.newJob(JobHelloQuartz.class) // 定义Job类为JobHelloQuartz
.withIdentity("helloJob", "group1") // 定义name/group
.usingJobData("name", "Leytton") // 定义属性
.build();
// 加入这个调度
scheduler.scheduleJob(job, trigger);
// 启动之
scheduler.start();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("Quartz start at " + sdf.format(new Date()));
// 运行一段时间后关闭
// Thread.sleep(10000);
// scheduler.shutdown(true);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
日志输出
Quartz start at 2018-04-13 11:38:26
group1.helloJob say hello to Leytton at 2018-04-13 11:38:31
group1.helloJob say hello to Leytton at 2018-04-13 11:38:33
如果定义.startAt(new Date(System.currentTimeMillis() - 5000))
// 5秒前执行,2秒执行一次,共执行2次,那么程序启动的时候会一次性执行完2次
Quartz start at 2018-04-13 11:50:08
group1.helloJob say hello to Leytton at 2018-04-13 11:50:08
group1.helloJob say hello to Leytton at 2018-04-13 11:50:08
若是4秒执行一次,那么程序启动的时候会执行2次
.withIntervalInSeconds(4)
若是6秒执行一次,那么程序启动的时候会执行1次,1秒后再执行1次
.withIntervalInSeconds(6)
Quartz start at 2018-04-13 11:53:21
group1.helloJob say hello to Leytton at 2018-04-13 11:53:21
group1.helloJob say hello to Leytton at 2018-04-13 11:53:22
三、使用案例
0x01每天执行一次
这种情况应该是最常见的了,目前用到的定时任务绝大部分是这种类型的
以下为每天凌晨4点执行一次
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//每天4点执行BEGIN################################
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.HOUR_OF_DAY, 4);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
//如果当天时间已过,则安排第二天开始,否则会立即执行一次
//if(System.currentTimeMillis()>cal.getTimeInMillis()) {
// cal.add(Calendar.DAY_OF_YEAR, 1);
//}
Date startTime=cal.getTime();
Trigger trigger_xx = TriggerBuilder.newTrigger().withIdentity("trigger_xx", "group1")
.startAt(startTime)
.withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule()
.withIntervalInDays(1))
.build();
JobDetail job_xx = JobBuilder.newJob(Job_xx.class)
.withIdentity("job_xx", "job_group1")
.build();
scheduler.scheduleJob(job_xx, trigger_xx);
scheduler.start();
N天执行一次
.withIntervalInDays(N))