quartz.properties:位于classpath目录
# 配置主调度器属性
org.quartz.scheduler.instanceName=QuartzScheduler
org.quartz.scheduler.instanceId=AUTO
# 配置线程池
# Quartz线程池的实现类
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 线程池的线程数量,配置为1一个任务最多起一个线程,如果下一次调度来临时上一次任务未执行完,则下一次任务会延迟执行。
org.quartz.threadPool.threadCount=1
# 线程池里线程的优先级
org.quartz.threadPool.threadPriority=5
# 配置作业存储
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
主程序:负责配置调度器、触发器、任务细节
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import job.MyJob;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
public class Main {
public static void main(String[] args) throws SchedulerException {
Main start = new Main();
start.go();
}
public void go() throws SchedulerException {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetail job1 = newJob(MyJob.class).withIdentity("job1", "group1").build();
Trigger trigger1 = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("1,2,3 * * * * ?")).build();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = scheduler.scheduleJob(job1, trigger1);
System.out.println(df.format(date1));
scheduler.start();
try {
Thread.sleep(60 * 1000L);
} catch (Exception e) {
e.printStackTrace();
}
scheduler.shutdown(true);
int n = scheduler.getMetaData().getNumberOfJobsExecuted();
System.out.println(n);
}
}
具体的任务执行类,要实现Job接口:
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class MyJob implements Job{
private boolean isRunning = false;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
String jobName = context.getJobDetail().getKey().getName();
if(!isRunning){
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(jobName + " ___________ " + df.format(new Date()));
isRunning = true;
}else{
System.out.println("MyJob is already running!");
}
}
}
分析:
//首先,一个完整的调度程序分三部分:任务、调度器、触发器。
//调度器的作用是负责调度整个调度程序的启动,停止。和按照触发器的触发信号来调度任务的运行。
//触发器就像一个计时器,按照提前指定的规则触发执行信号。
//任务自然是实际要完成的工作。
//程序中先创建一个调度器:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//让调度程序开始
scheduler.start();
//让调度程序结束
scheduler.shutdown(true);
//返回调度器一共调度执行任务的次数。
scheduler.getMetaData().getNumberOfJobsExecuted();
//把触发器和任务添加到调度器中,调度器就会按照定义好的触发器的触发信号来执行定义好的任务。
//这个方法返回任务的第一次调用时间。
//当然如果此时还没调用start()方法任务不会执行,但是会在调用start()方法时立即补上执行应执行而未执行的那几次任务。
scheduler.scheduleJob(job1, trigger1);
//创建一个名字为job1,分组为group1的任务,任务的定义为MyJob类。
JobDetail job1 = newJob(MyJob.class).withIdentity("job1", "group1").build();
//其中newJob方法是org.quartz.JobBuilder类的一个静态方法,这里用了import static静态引入。
//每一个任务都是一个MyJob类的对象实例。要求MyJob类有个无参构造方法。
//创造一个名字为trigger1,分组为group1的触发器,按照cron表达式指定的规则触发执行信号。
Trigger trigger1 = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("1,2,3 * * * * ?")).build();
//其中newTrigger方法是org.quartz.TriggerBuilder类的一个静态方法,这里用了import static静态引入。
//触发器分两种,一种是简单触发器,一种是cron触发器,上面用的第二种,手动指定cron表达式
定义一个简单触发器,简单触发器只能指定什么时候执行第一次,间隔多久执行下一次,和一共重复执行几次:
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
//立即开始执行,并每间隔2s执行一次,共重复3次,所以任务一共会执行4次(第1次和重复3次)。
trigger1 = newTrigger()
.withIdentity("trigger1", "group1")
.startAt(new Date())
.withSchedule(
simpleSchedule()
.withIntervalInSeconds(2)// 重复间隔2s
.withRepeatCount(3)) // 重复次数3次,若一直重复用.repeatForever()
.build();
可以看出newTrigger方法返回一个TriggerBuilder类,这个类通过一些方法进行触发器配置,最后调用build方法返回构造的触发器。(以上用的链式写法)
而简单触发器或cron触发器并没有本质区别,只是在配置的时候传入withSchedule方法的参数不同,当然定时规则也可能不同。