二. Scheduler 的开启,关闭和挂起
开启是 start(), 与以前一样, 重点是讲解一下 Scheduler 关闭和挂起。
二.一 关闭 shutdown() 及shutdown(flag)
二.一.一 工作任务类
//shutdown 用法 public class MyJob10 implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //要做的事,是打印当前的时间 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化时间 String dateString=sdf.format(new Date()); System.out.println("备份数据库的时间是:"+dateString); } }
二.一.二 主程序测试
二.一.二.一 直接关闭
//shutdown 关闭 public class SchedulerDemo10 { public static void main(String[] args) throws Exception{ //获取Scheduler Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler(); // 创建 JobDetail JobDetail jobDetail=JobBuilder.newJob(MyJob10.class) .withIdentity("job1","group1") .build(); //创建 Trigger Trigger trigger= TriggerBuilder.newTrigger() .withIdentity("trigger1","group1") //设置标识 .startNow() .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(2)) // 设置为简单触发器 .build(); //关联 job和 trigger scheduler.scheduleJob(jobDetail,trigger); //启动 scheduler scheduler.start(); //直接关闭 scheduler.shutdown(); } }
运行程序,此时控制台打印输出:
直接关闭,没有任何任务执行。
二.一.二.二 休眠后关闭
改变代码,在关闭之前添加上休眠的代码
//休眠10s后,关闭 Thread.sleep(10000); scheduler.shutdown();
运行程序,控制台打印输出:
共执行任务6次,(最开始时 1次+休眠时5次=6次),10s之后,关闭了调度器。
二.一.二.三 关闭后重新开启
关闭之后,是否能重新开启呢?
改变代码, 在 二.一.二.二 的基础上再添加一个 ‘重新启动’ 的代码
//休眠10s后,关闭 Thread.sleep(10000); scheduler.shutdown(); //休眠2s之后,重新启动 Thread.sleep(2000); scheduler.start();
运行程序,控制台打印输出:
Exception in thread “main” org.quartz.SchedulerException: The Scheduler cannot be restarted after shutdown() has been called.
同时注意一下, 调度器的关闭顺序
13:02:05,625 INFO QuartzScheduler:666 - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down. 13:02:05,625 INFO QuartzScheduler:585 - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused. 13:02:05,626 INFO QuartzScheduler:740 - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete.
二.一.三 shutdown() 的参数
调用shutdown() 关闭方法时,也可以传入参数
void shutdown(boolean waitForJobsToComplete) throws SchedulerException;
参数 true 和false, 是有一定的区别的, 下面检测一下。
二.一.三.一 任务调度里面添加 休眠
//shutdown 用法 public class MyJob10 implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //添加休眠,验证一下 shutdown(flag) 的参数 try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } //要做的事,是打印当前的时间 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化时间 String dateString=sdf.format(new Date()); System.out.println("备份数据库的时间是:"+dateString); } }
二.一.三.二 shutdown() 默认时
//shutdown 关闭 public class SchedulerDemo10 { public static void main(String[] args) throws Exception{ //获取Scheduler Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler(); // 创建 JobDetail JobDetail jobDetail=JobBuilder.newJob(MyJob10.class) .withIdentity("job1","group1") .build(); //创建 Trigger Trigger trigger= TriggerBuilder.newTrigger() .withIdentity("trigger1","group1") //设置标识 .startNow() .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(2)) // 设置为简单触发器 .build(); //关联 job和 trigger scheduler.scheduleJob(jobDetail,trigger); //启动 scheduler scheduler.start(); //休眠10s后,关闭 Thread.sleep(10000); //默认时 scheduler.shutdown(); } }
控制台打印输出:
shutdown complete 在中间。
二.一.三.三 shutdown (false) 时
//休眠10s后,关闭 Thread.sleep(10000); // 为false 时 scheduler.shutdown(false);
控制台打印输出:
shutdown complete 在中间。
结果,与默认时是一样的。
二.一.三.四 shutdown(true) 时
//休眠10s后,关闭 Thread.sleep(10000); // 为true 时 scheduler.shutdown(true);
控制台打印输出:
shutdown complete 在最后。
当 shutdown() 方法 传入 true时, 表示会等所有任务队列里面的任务运行完成后,才关闭。 传入false时,是直接关闭。
注意,无论是直接关闭 false,还是等运行完成后关闭 true, 都不会影响任务队列里面的任务继续运行。
二.二 挂起 standby()
挂起并不是关闭,只是暂时停止运行, 等一段时间后,是可以再次 start() 开启的。
二.二.一 任务接口
//挂起 public class MyJob11 implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //要做的事,是打印当前的时间 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化时间 String dateString=sdf.format(new Date()); System.out.println("备份数据库的时间是:"+dateString); } }
二.二.二 主程序测试
//挂起 standby public class SchedulerDemo11 { public static void main(String[] args) throws Exception{ //获取Scheduler Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler(); // 创建 JobDetail JobDetail jobDetail=JobBuilder.newJob(MyJob11.class) .withIdentity("job1","group1") .build(); //创建 Trigger Trigger trigger= TriggerBuilder.newTrigger() .withIdentity("trigger1","group1") //设置标识 .startNow() .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(2)) // 设置为简单触发器 .build(); //关联 job和 trigger scheduler.scheduleJob(jobDetail,trigger); //启动 scheduler scheduler.start(); //休眠10s后,挂起 Thread.sleep(10000); scheduler.standby(); //挂起10s后,重新开启 Thread.sleep(10000); scheduler.start(); } }
二.二.三 控制台打印输出
挂起时间的那五次操作,又给补回来了,重复执行了5次。
如果这个任务执行的是数据库插入的操作,那么这个操作就会执行5遍,产生5条除id外相同的记录。
这样是不行的。
有没有一种方式,可以像数据库那样有个锁, 当队列里面有任务未执行结束时,不能进入?
有的,@DisallowConcurrentExecution 注解。