一文带你彻底了解Spring的定时任务调度

本文我们聊一下Spring定时任务调度。这个主题,相信大家都比较熟悉,平时用的应该也比较多。不过说起实现原理,了解的小伙伴应该就不太多了,网上对应的文章虽然很多,不过基本都是使用教程。即使有少部分提及原理,说的也是含糊不清,更有甚者是胡说八道。

 其实Spring的定时任务调度,并不神秘,也不是Spring特有的,本质还是借助JDK的能力实现的,只是在使用方式上更Spring一点,也就是更简洁、更便捷一点。

关于JDK的定时任务,主要是借助 ScheduledThreadPoolExecutor实现的,感兴趣的小伙伴可以可以自行了解其实现原理。这里我们主要聊Spring的相关细节,关于JDK部分我们不会详细介绍。

当然,如果你们有需要,恰巧我也有时间的话,也可以拿出来说一说,毕竟说啥不是说呢,是吧。

1. Spring定时任务的类型

 关于Spring定时任务的使用,小伙伴们应该都比较熟悉,就是直接在方法上加上@Scheduled注解即可。Spring会根据你指定的频率,定时调度该方法的执行,这一点完全不用你关心。

 使用自然是很简单的,这是Spring一贯的风格。关于Spring是怎么做的,读过贰师兄前面文章的小伙伴应该也可以猜到,至少得先把这些标注了@Scheduled注解的定时方法找出来,然后在想办法让它定时执行。当然前面我们也说了,这部分是借助JDK的能力来实现的。

 但是在使用Spring定时调度的过程,也有一些细节需要先和小伙伴们介绍清楚。首先就是Spring支持的三种类型任务的执行逻辑,这里恐怕能说清楚的小伙伴们不多,尤其是在碰到单线程模型,我们先梳理一下:

Spring支持CRON表达式类型、fixedDelay间隔执行、fixedRate间隔执行三种任务类型。关于这三种类型在任务执行上的差别,我们一一介绍一下。

1.1 CRON表达式类型任务

 关于CRON表达式含义,这里我们不再介绍,相信小伙伴们都比较熟悉,实在不熟悉自行查阅资料吧。

 我们要说的是,在单线程执行的情况下,如果CRON任务执行时间过长,以至于下次执行的时间都到了,但是上次任务还没有执行结束,下次任务要怎么办。

 这里先给结论:放弃,也就是下一次任务执行就被放弃了,也就是少执行了一次。这里拿任务设置为每五秒执行一次的表达式,说明一下:

  1. 假设10:00:00s时,任务第一次执行,但是任务执行时间很长,执行了7s。
  2. 根据任务的执行计划,10:00:05s时,应该要执行第二次任务,但是此时发现有任务在执行(上一次任务需要执行到10:00:07s),那么,此次执行计划直接放弃,也就是本次任务不执行了
  3. 根据任务的执行计划,10:00:10s时,应该要执行第三次任务,此时发现没有任务执行,本次任务正常执行。

 这里大家一定要注意,单线程模型下,由于第一次任务执行时间较长,导致第二次任务不执行,也就是少执行了一次。这里可能会影响预期、从而产生业务影响。

1.2 fixedDelay间隔类型任务

 fixedDelay是最简单的一种方式模型,间隔执行:也就是延迟指定的间隔后,再次执行下次任务。计算公式为:下次执行时间 = 上次任务执行结束时间 + 间隔时间。相同的问题:如果任务执行时间较长,下次执行时间也会晚于预期。这里以任务间隔为五秒,说明一下:

  1. 假设10:00:00s时,任务第一次执行,任务执行时间较长,执行了7s。
  2. 第一次任务执行结束后(10:00:07),等待5s后,再次执行下一次任务(10:00:12),第二次任务执行了3s。
  3. 第二次任务执行结束后(10:00:15),等待5s后,再次执行下一次任务,依此类推。

 这里需要注意,单线程模型下,如果存在任务执行时间较长,整体的执行计划都会往后顺延

1.3 fixedRate间隔类型任务

 fixedRate也是间隔执行的方式,只是这个间隔不是按照任务结束时间计算的,而是按照开始时间。计算公式为:下次执行时间 = 上次任务执行开始时间 + 间隔时间。当然,如果任务执行时间较长,超过间隔时间,下次执行时间也要顺延,毕竟不能强暴的直接打断吧。

 不过fixedRate会将间隔会自动缩小,尽量追赶计划执行时间,一旦赶上或者追平,继续按照指定间隔执行。这里还是以间隔为五秒的情况,说明一下:

  1. 假设10:00:00s时,任务第一次执行,任务执行时间较长,执行了7s。
  2. 根据任务的执行计划,10:00:05s时,应该要执行第二次任务,但是此时第一次任务还在执行中,所以第二次执行时间只能等待顺延。
  3. 第一次任务执行结束后(10:00:07),发现已经晚于第二次执行的计划时间了。会追赶进度,所以第二次任务立即执行。
  4. 这里假设第二次任务只需要执行2s,在10:00:09就执行结束了。计划第三次执行时间为:10:00:10,也就是第二次任务已经追平了,无需继续追赶,此时会遵循计划,在10:00:10时,正常执行第三次任务。

 这里需要注意,fixedRate会自动调整间隔,使任务尽快追平计划时间,追平后遵循计划执行。当然这里讨论的也是单线程模型下。

 好了,关于定时任务的三种类型的讨论就这么多。大家注意在单线程模型下,上面的讨论才有意义。大家清楚不同任务类型,发生任务执行时间过长,对下次执行时间的影响即可。再次强调,是单线程模型下,如果是多线程执行,影响情况需要结合线程池配置分析了,这里我们不具备讨论条件。

这里为什么执着的讨论单线程模型,因为Spring默认的就是单线程模型,而往往我们又不指定调度线程池。所以其实单线程模型才是最最常用的。

2. @Scheduled注解解析

 通过上一章节对Spring三种定时任务类型的介绍,相信小伙伴们已经很清楚他们之间的区别了。在Spring中,定时任务都是由@Scheduled标识的,三种任务类型分别对应@Scheduled的三种属性,分别是cronfixedDelayfixedRate,设置对应的值,即为开启对应类型的任务。

 我们在上面也介绍过了,Spring要执行这些定时任务,第一步就是需要先解析出来这些定时任务,然后才能交由JDK处理。那么本章节我们就来看一下解析过程。

2.1 @EnableScheduling开启任务调度功能

 在探索解析流程之前,我们先介绍一下@EnableScheduling。大家知道,在使用Spring的定时任务调度功能前,是需要在类上先添加@EnableScheduling开启的,这究竟有什么用呢。

 关于Spring的@EnableXXX,通常到时开启某种能力,比如EnableScheduling开启定时任务调度、 @EnableAsync开启异步调用等。其实原理也很简单,都是借助@Import能力导入某些BeanPostProcessor(也有可能是其他类型的),这些BeanPostProcessor,会在bean的生命周期的各个流程发挥重要作用,从而使Spring具有强大的能力。

 关键这个过程完全是可插拔的,加入某个BeanPostProcessor,就具备响应能力了,拓展能力极强。这也正是@EnableXXX的原理,可以简单理解为:开启某项功能。

BeanPostProcessor是Spring留给我们的一种拓展方式,能力非常强悍,甚至很多Spring的核心能力,比如@AutoWired@Resource属性注入,都是借助它实现的。当然,@EnableXXX

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。 Quartz的优势: 1、Quartz是一个任务调度框架(库),它几乎可以集成到任何应用系统中。 2、Quartz是非常灵活的,它让您能够以最“自然”的方式来编写您的项目的代码,实现您所期望的行为 3、Quartz是非常轻量级的,只需要非常少的配置 —— 它实际上可以被跳出框架来使用,如果你的需求是一些相对基本的简单的需求的话。 4、Quartz具有容错机制,并且可以在重启服务的时候持久化(”记忆”)你的定时任务,你的任务也不会丢失。 5、可以通过Quartz,封装成自己的分布式任务调度,实现强大的功能,成为自己的产品。6、有很多的互联网公司也都在使用Quartz。比如美团 Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度。   课程说明:在我们的日常开发中,各种大型系统的开发少不了任务调度,简单的单机任务调度已经满足不了我们的系统需求,复杂的任务会让程序猿头疼, 所以急需一套专门的框架帮助我们去管理定时任务,并且可以在多台机器去执行我们的任务,还要可以管理我们的分布式定时任务。本课程从Quartz框架讲起,由浅到深,从使用到结构分析,再到源码分析,深入解析Quartz、Spring+Quartz,并且会讲解相关原理, 让大家充分的理解这个框架和框架的设计思想。由于互联网的复杂性,为了满足我们特定的需求,需要对Spring+Quartz进行二次开发,整个二次开发过程都会进行讲解。Spring被用在了越来越多的项目中, Quartz也被公认为是比较好用的定时器设置工具,学完这个课程后,不仅仅可以熟练掌握分布式定时任务,还可以深入理解大型框架的设计思想。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值