pring Scheduler定时器原理分析
Posted anxinliang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pring Scheduler定时器原理分析相关的知识,希望对你有一定的参考价值。
首先我们看看简单定时器实现方法:用ScheduledExecutorService接口
public interface ScheduledExecutorService extends ExecutorService { 创建并执行在给定延迟后启用的一次性操作。 ScheduledFuture<?> schedule(Runnable command,long delay,TimeUnit unit); 创建并执行在给定延迟后启用的 ScheduledFuture。 <V> ScheduledFuture<V> schedule(Callable<V> 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 秒钟蜂鸣一次:
里面几个方法其中说到的当业务中出现异常后,就不会执行后续定时任务了,所以如果要用ScheduledExecutorService 写一些自己的业务定时任务,务必要知道这点。
再来说说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()
通过schedule方法及run方法互相调用,再利用ScheduledExecutorService接口的schedule(Runnable command,long delay,TimeUnit unit)单次执行效果,从而实现一定时间重复触发的效果。
以上说的都是以@Scheduled(cron = "0 0 2,13,16 ? * *")和默认配置下执行的,调用的TaskScheduler的ConcurrentTaskScheduler实现类,默认单个线程执行。
要以线程池执行的话,需要配置:
<task:annotation-driven scheduler="myScheduler"/>
<task:scheduler id="myScheduler" pool-size="20"/>
给出几个结论:
调度器本质上还是通过juc的ScheduledExecutorService进行的
调度器启动后你无法通过修改系统时间达到让它马上执行的效果
被@Schedule注解的方法如果有任何Throwable出现, 不会中断后续Task, 默认只会打印Error日志,定时任务不会同时被触发。
以上是关于pring Scheduler定时器原理分析的主要内容,如果未能解决你的问题,请参考以下文章
Cocos2d-x 源代码分析 : Scheduler(定时器) 源代码分析
深入了解cocos2d-x 3.x定时器(scheduler)的使用和原理探究
深入了解cocos2d-x 3.x定时器(scheduler)的使用和原理探究