当前位置: 首页 - 数码 - Spring Scheduler定时器原理分析

Spring Scheduler定时器原理分析

2024-12-19 数码 0

Spring Scheduler定时器原理分析

首先我们看看简单定时器实现方法:用ScheduledExecutorService界面

public interface ScheduledExecutorService extends ExecutorService

{

建立并执行在给定延迟后启用的一次性操作。

ScheduledFuture> schedule(Runnable command,long delay,TimeUnit unit);

建立并执行在给定延迟后启用的 ScheduledFuture。

ScheduledFuture schedule(Callable callable,long delay,TimeUnit unit);

建立并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的任何一个执行遇到异常,则后续执行都会被取消。否则,只能通过执行程式的取消或终止方法来终止该任务。如果此任务的任何一个执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行。

ScheduledFuture> scheduleAtFixedRate(Runnable command,long initialDelay,long period, TimeUnit unit);

建立并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任务的任一执行遇到异常,就会取消后续执行。否则,只能通过执行程式的取消或终止方法来终止该任务。

ScheduledFuture> scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit);

}

用法示例

以下是一个带方法的类,它设定了 ScheduledExecutorService ,在 1 小时内每 10 秒钟蜂鸣一次:

import static java.util.concurrent.TimeUnit.*;

class BeeperControl {

private final ScheduledExecutorService scheduler =

Executors.newScheduledThreadPool(1);

public void beepForAnHour() {

final Runnable beeper = new Runnable() {

public void run() { System.out.println(beep); }

};

final ScheduledFuture> beeperHandle =

scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);

scheduler.schedule(new Runnable() {

public void run() { beeperHandle.cancel(true); }

}, 60 * 60, SECONDS);

}

}

[color=red]里面几个方法其中说到的当业务中出现异常后,就不会执行后续定时任务了,所以如果要用ScheduledExecutorService 写一些自己的业务定时任务,务必要知道这点。[/color]

再来说说Spring Scheduler。

Spring3.0之后增加了排程器功能, 提供的@Schedule等等注解, 那么它内部是如何实现的呢?

核心类摘要:

1.ScheduledAnnotationBeanPostProcessor

2.ScheduledTaskRegistrar

3.TaskScheduler

4.ReschedulingRunnable

具体说明:

1.ScheduledAnnotationBeanPostProcessor

(1)核心方法:Object postProcessAfterInitialization(final Object bean, String beanName)

功能:负责@Schedule注解的扫描,构建ScheduleTask

(2)核心方法:onApplicationEvent(ContextRefreshedEvent event)

功能:spring容器载入完毕之后呼叫,ScheduleTask向ScheduledTaskRegistrar中注册, 呼叫ScheduledTaskRegistrar.afterPropertiesSet()

2.ScheduledTaskRegistrar

(1)核心方法:void afterPropertiesSet()

功能:初始化所有定时器,启动定时器

3.TaskScheduler

主要的实现类有三个 ThreadPoolTaskScheduler, ConcurrentTaskScheduler,TimerManagerTaskScheduler

作用:这些类的作用主要是将task和executor用ReschedulingRunnable包装起来进行生命周期管理。

(1)核心方法:ScheduledFuture schedule(Runnable task, Trigger trigger)

4.ReschedulingRunnable

(1)核心方法:public ScheduledFuture schedule()

(2)核心方法:public void run()

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;

}

}

@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();

}

}

通过schedule方法及run方法互相呼叫,再利用ScheduledExecutorService界面的schedule(Runnable command,long delay,TimeUnit unit)单次执行效果,从而实现一定时间重复触发的效果。

以上说的都是以@Scheduled(cron = 0 0 2,13,16 ? * *)和预设配置下执行的,呼叫的TaskScheduler的ConcurrentTaskScheduler实现类,预设单个执行绪执行。

要以执行绪池执行的话,需要配置:

给出几个结论:

排程器本质上还是通过juc的ScheduledExecutorService进行的

排程器启动后你无法通过修改系统时间达到让它马上执行的效果

被@Schedule注解的方法如果有任何Throwable出现, 不会中断后续Task, 预设只会打印Error日志,定时任务不会同时被触发。

标签: 9v23数码之家比价网中关村zol官网电子产品有哪些pc是什么意思

上一篇:vivo Y76s星夜黑体验如同oppoa55般的闪充神器彻底抚慰你的电量焦虑

下一篇:网络科技公司数字化梦想的织匠们

相关推荐
推荐资讯
热门文章