您的位置:首页 > 编程语言 > Java开发

Spring Scheduling详解

2016-02-29 18:18 681 查看
一、Spring scheduling包结构
包位于spring-context中,共包含如图所示的几个包。


二、scheduling包




本文着重讲解TaskScheduler、Trigger、TriggerContext。
(1) TaskScheduler
这个接口有以下方法:

//按照Trigger指定的下一次的执行时间执行一个任务ScheduledFuture schedule(Runnable task, Trigger trigger);
//按照指定的时间执行任务
ScheduledFuture schedule(Runnable task, Date startTime);

//按照固定的时间间隔执行任务,第一次开始执行的时间由startTime指定,period指定执行间隔//时间间隔指每次任务开始的时间ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
//按照固定的时间间隔执行任务,period指定执行间隔,时间间隔指每次任务开始的时间
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);

//按照固定的时间间隔执行任务,时间间隔指任务的结束到下一次任务开始之间的时间,delay指定时间//间隔,startTime指定第一次任务的开始时间
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);

//按照固定的时间间隔执行任务,时间间隔指任务的结束到下一次任务开始之间的时间,delay指定时间//间隔
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
(2)Trigger
这个接口只有一个方法

Date nextExecutionTime(TriggerContext triggerContext);
这个方法用于获得任务的下一次执行日期
(3)TriggerContext
这个接口提供三个方法,
//获得上次任务计划执行的日期
Date lastScheduledExecutionTime();
//获得上次任务实际的执行日期
Date lastActualExecutionTime();
//获得上次任务的完成日期
Date lastCompletionTime();
三、scheduling.concurrent包



(1)ConcurrentTaskExecutor
spring中的并发任务执行器,实现了java.util.concurrent中的Executor接口。
类中有一个Executor对象和TaskExecutorAdapter对象。

TaskExecutorAdapter位于org.springframework.core.task.support包中,
是一个Executor适配器,实现了Executor接口,其中有一个Executor对象。
当注入的Executor实现了ExecutorService接口时,直接调用Executor执行,并返回一个Future。如果未实现ExecutorService接口,则创建一个FutureTask,并利用Executor执行该FutureTask,并返回该FutureTask。

(2)ConcurrentTaskScheduler
ConcurrentTaskScheduler实现了TaskScheduler接口,继承了ConcurrentTaskExecutor类。
ConcurrentTaskScheduler中有一个ScheduledExecutorService对象,当不向ConcurrentTaskScheduler中注入ScheduledExecutorService时,类内部会利用Executors.newSingleThreadScheduledExecutor()创建一个单线程的ScheduledExecutorService对象。
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
try {
ErrorHandler errorHandler =
(this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule();
}
catch (RejectedExecutionException ex) {
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
}
}
schedule(Runnable task, Trigger trigger)的实现如上述代码。
方法内部新建一个ReschedulingRunnable类,通过构造方法注入任务、Trigger、ScheduledExecutorService等。
public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) {
super(delegate, errorHandler);
this.trigger = trigger;
this.executor = executor;
}
public ScheduledFuture schedule() {
synchronized (this.triggerContextMonitor) {
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
if (this.scheduledExecutionTime == null) {
return null;
}
long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
return this;
}
}
然后通过调用上述方法执行计划任务。

ReschedulingRunnable类内部覆盖了run()方法。
@Override
public void run() {
Date actualExecutionTime = new Date();
super.run();
Date completionTime = new Date();
synchronized (this.triggerContextMonitor) {
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
if (!this.currentFuture.isCancelled()) {
schedule();
}
}
}


本文出自 “飞鱼技术” 博客,请务必保留此出处http://flyingfish.blog.51cto.com/9580339/1746120
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: