工作中要用到quartz来实现定时任务的触发,任务的触发和暂停都涉及到scheduler,而scheduler的获取方式如下两行代码
private static SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sche = sf.getScheduler();
于是有点困惑,如果只将sf设置成全局变量,在触发和暂停的方法里分别获取scheduler,那获取的scheduler总是同一个吗?
如果不是同一个,意味着scheduler必须设置为全局变量。
也许这个问题对于老手来说根本不值一提,不过谁叫我是新手呢。
来吧,实验一下。
package test.quartz;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzManager {
// protected static final Logger logger = LoggerFactory
// .getLogger(QuartzManager.class);
private static SchedulerFactory sf = new StdSchedulerFactory();
public static void main(String[] args){
try {
Scheduler sche = sf.getScheduler();
sche.start();
JobDetail job = JobBuilder.newJob(Hello.class).withIdentity("name","group").build();
JobKey jobKey = job.getKey();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?")).build() ;
System.out.println(jobKey.toString());
System.out.println(sche.checkExists(jobKey));
Scheduler ss = sf.getScheduler();
ss.scheduleJob(job, trigger);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(trigger.getKey());
System.out.println(ss.checkExists(jobKey));
System.out.println(sche.checkExists(jobKey));
sche.unscheduleJob(trigger.getKey());
System.out.println(sche.unscheduleJob(trigger.getKey()));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
实现job接口的Hello类如下。
package test.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class Hello implements Job{
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("aaa");
}
}
在写代码时要注意两点(其实就是我写错的地方)
1. CronTrigger的格式 每5s一次必须是 /5 * * * ? ;第一次写成5 * * * * ?,是指每分钟的第5s。
2. scheduler必须调用start()方法才能开始调度任务,start方法可以在scheduleJob之前,也可以在其之后。也就是说,先把任务放进去,再start调度器也是可以的(个人感觉这么安排不符合功能的逻辑,所以还是按照先start调度器,再放任务进去比较好。)
通过以上,变换了几次代码之后,获得的结论:
1. 这个schedulerFactory中获取的scheduler,总是同一个。
2. jobKey是group.name
3. 可以给一个scheduler起多个名字,比如下面,但是本质上这两个还是同一个scheduler,也就是说,可以用sf来布置任务,用ss来停止任务。
Scheduler sf = sf.getScheduler(); Scheduler ss = sf.getScheduler();
4. . 根据我的观察,unscheduleJob方法的返回值是bool型,如果成功撤销,返回true;
另,和mentor说了结论1后,mentor说,这测试的是schedulerFactory对于产生scheduler是单例,要去或者这个factory的注册表查询到底生成了多少个schedler。其实对这里还是不是很了解。后续清楚后要来写。