If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
Java的ScheduledExecutorService,定时调度器,可以实现按一定周期执行某个任务的功能,它的scheduleAtFixedRate方法,定期执行某个任务,当任务执行时间过长,超过它的周期时,如果当前任务没有执行完成,是不会开始下一次的任务的。
这有一个好处就是,可以预防任务堆积导致工作线程都被占满的情况。
public class AddedUpJob implements Runnable{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+new Date());
try {
Thread.sleep(300000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after 5 minute ,end up the job.");
}
}
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
AddedUpJob job = new AddedUpJob();
executor.scheduleAtFixedRate(job, 1, 5, TimeUnit.SECONDS);
}
验证一下,如果工作任务休眠一段时间,超过了定时的周期,那么下一轮定时任务会等待该任务执行完成后才开始。
这点跟Quartz的定时调度方法不一样,Quartz会按照调度周期,执行相应的定时任务,任务之间都是独立的,所以可能出现任务堆积的情况。另外Spring集成quartz时,每次取到的Shedule对象都是同一个,说明Quartz的调度器类默认的是单例。
SchedulerFactory sf1 = new StdSchedulerFactory();
Scheduler scheduler1 = sf.getScheduler();
SchedulerFactory sf2 = new StdSchedulerFactory();
Scheduler scheduler2 = sf.getScheduler();
System.out.println(scheduler1 ==scheduler2);
输出结果为true。当初选用Quartz作为定时任务的调度工具,是因为它强大可配置的Cron表达式,但是对于频繁执行的、而且执行时间较长的任务来说,很容易将Quartz的工作线程耗尽,从而影响其他任务的正常执行。所以只能分开处理了。