Spring框架SpringBoot定时任务深入教程_第1页
Spring框架SpringBoot定时任务深入教程_第2页
Spring框架SpringBoot定时任务深入教程_第3页
Spring框架SpringBoot定时任务深入教程_第4页
Spring框架SpringBoot定时任务深入教程_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Spring定时任务_为什么你的SpringTask定时任务没有定时执行? 版权声明:本文出自侠梦的开发笔记公众号,欢迎转载或交流请联系。 前言 定时任务的使用,在开发中可谓是家常便饭了,定时发送邮件、短信。避免数据库,数据 表过大,定时将数据转储。通知、对账等等。 当然实现定时任务的方式也有很多,比如使用linux下的contab脚本,jdk中自带的Timer 类。SpringTask或是Quartz。 相信你也有过如下的疑问: ?SpringTask的contab的表达式和linux下的contab有什么区别? ?crontab表达式记不住? ?定时任务阻塞会有什么影响? ?多个定时任务的

2、情况下是如何运行的? ?具有相同表达式的定时任务,他们的执行顺序如何? ?为什么async异步任务没有生效? 所以这篇文章,我们来介绍一下,在SpringTask中,定时任务的执行原理及相关问题。演示环境为SpringBoot项目。 SpringBoot定时任务的原理 相信绝大部分开发者都使用过SpringBoot为我们提供的定时任务的Starter和定时任务 的注解。所以我们来主要介绍一下SpringBoot实现定时任务的原理,和其相关注解的作 用。 Spring在3.0版本后通过Scheduled注解来完成对定时任务的支持。 *f?eutIicTMaric util6rDaveSycr *

3、 EautlKjrCftrijBedEJ * 自力工n心白3.0. * 宿ge-EnaJ?lecediiling T,seecAedLiJ.edAnJIOtJ.o_n5enPostProcessor vsee匚五巨dn_l当与 STazget(ElementTiTCDtElementType,AOTAr:Retention(RetentionPclicy. 3Documented 3Repeatable(Schedules.elBa) publicinrezfaceScheduled(| 在我们使用时,需要在Application启动类上加上EnableScheduling注解,它是从Spri

4、ng3.1后开始提供的。 autlterGr工皆B仝antsma口七Laj-Jirerg-er.ffoei-lergWiHGG3*1 ScAeduled SoJiod让上inggnfigur吕tzin Scheditling8ngrsr ths-dirledT3mkfleh卫stzrar Trig-g-er ScheduiedAnnotationBeanPostProcessor STargst(ElsrLetTiTS.TYPE ionR_ettfi.CifinPalLc.二心工二.空 Import(Scliedu.lin.gCoD.fLguratian.class)SDocumented.

5、publicWinterfaceEnm11135chi匕duling 由于现在Spring3版本较低,使用得比较少了,可能并不会考虑太多细节,大多只需要关注目标实现,所以我们在配套使用两个注解的时候,并不会出现什么问题。 在3.0中,是通过 便,白白田台白白ssefsee 上述的XML配置和Scheduled配合实现定时任务的,而我们这里的 EnableScheduling其实类似的和它等价,是用来发现注解了Scheduled的方法,没 有这个注解光有Scheduled是无法执行的,大家可以做一个简单案例测试一下,其底层是Spring自己实现的一套定时任务的处理逻辑,所以使用起来比较简单。 任

6、务一直阻塞会怎么样? 介绍了两个注解的作用后,我们来开始做实验,简单的写一个定时执行的方法。 longsheepNum-一3叩巧曲:Q SchdiiLedCClKeciRate-2O_0QO)g业工工二vaxduaskzlClt |DaceFormat;df=newSLnqpleDateFormat(*yyyy-MM-ddHH:imn;sshJ; ,out;.print;Ln(df.fOmaL(newDateO)+r|+sheepNunn- 每隔20s输出一句话,在输出几行记录后,打上了一个断点。 对后续的任务有什么影响呢? 2020-03-2118:01:35 门自山来数羊3 2020-03

7、-2118:口 4;55:task数羊 4 2020-03-2118:06:26Mask 来数羊 5 2020-03-2118:06:29:task 来数羊 6 2020-03-2118:06:29 或来数羊 7 2020-03-2118:06:29Mask5Ms 羊 8 可以看到,断点时的后续任务是阻塞着的,从图上,我们还可以看出初始化的名为pool-1-thread-1的线程池同样证实了我们的断点前 断点后 本该 6:15 排行阻塞了 11 秒 想法,线程池中只有一个线程,创建方法是: Executors.newSingleThreadScheduledExecutor(); 从这个例子来

8、看,断点时,任务会一直阻塞,当阻塞恢复后,会立马执行阻塞的任务。线程池内部时采用DelayQueue延迟队列实现的,它的特点是:无界、延迟、阻塞的一种队列,能按一定的顺序对工作队列中的元素进行排列。 1:add() KheduleAtFixedRateO selfeduFfxedDelayi. 多个定时任务的执行 通过上面的实验,我们知道,咋看默认情况下,任务的线程池,只会有一个线程来执行任务,如果有多个定时任务,它们也应该是串行执行的。 t3勺正11AAp.tasklsleep., 1asklsieep, tasklsleep. task121 从上图可以看出,一旦线程执行任务1后,就会睡眠

9、2分钟。线程在死循环内部一直处于 Running状态。 通过观察日志,根本没有任务2的输出,我们知道默认情况下,多个定时任务是串行执行的,类似于多辆车过单行道的桥,如果一个任务出现阻塞,其他的任务都会受到影响。 那如果线程池包含多个线程的情况下,多个定时任务并发的情况是什么样? 串行当然很好理解,就是上文说的汽车过桥,依次通过。再来理解并发,区别于并行,并发 是指一个处理器同时处理多个任务,而并行是指多个(核)处理器同时处理多个不同的任务。 并发不一定同一时间发生,而并行,指的是同一时间。 具有相同表达式的定时任务,他们的执行顺序如何? 从上面的实验同样能知道,具有相同表达式的定时任务,还是和

10、调度有关,如果是默认的线 程池,那么会串行执行,首先获取到cpu时间片的先执行。在多线程情况下,具体的先后 执行顺序和线程池线程数和所用线程池所用队列等等因素有关。 SpringTask和linuxcrontab的cron语法区另U? 两者的cron表达式其实很相似,需要注意的是linux的contab只为我们提供了最小颗粒 度为分钟级的任务,而java中最小的粒度是从秒开始的。具体细节如下图:Linu乂下的乂下的contsb *北上上 Illi+一一周中的一天周中的一天 。- -7)(Sund白尸白尸0。了。了OR | | | |十月十月(112ORjanf9bma, ,ap一一 |4日日(

11、1-31) | |十十一一/ /卜时(。卜时(。. .23)分分(0.59) Java(Springtask) K* jjjj+(0-7)(Sunday=0or7)ORsun.nnon | | | |十十- -月月(1-12)ORjaQ他他Hmar田田pr一一 | |/|/日日(1-31) | |斗小时斗小时(023) 十分十分(0-59) 秒(。秒(。- -59) 在cron语法中容易犯的错误 以spring中的task为例,cron表达式中/代表每的意思,“*/1减示每10个单位。 在cron语法中很多人会犯错误。比如要求写出每十分钟定时执行的cron语句,可能会有 以下版本的出现: :这

12、式(当前时间 W”3) 1Scheduled(cron=40/104 业杂业杂?)表不从。分钟开始,表不从。分钟开始,以以 1。分钟为单位间隔下分钟为单位间隔下 2Scheduled(cron 二、:二、:L0*?#)表示分钟数为表示分钟数为 10 的时候执行的时候执行(10 分钟的分钟的 A A Scheduled(cron=0-59/10 比比*?*)效果同效果同 1 40cheduled(crn=葭葭 0/10 小李洋小李洋?0 从第。秒开始,每隔从第。秒开始,每隔 10 分钟执行分钟执行所以当我们写完cron表达式的时候,可以适当的调低执行间隔时间来测试,或是通过一些在线的网站来检测你

13、的cron脚本是否正确。 Async异步注解原理及作用 Springtask中和异步相关的注解有两个,一个是EnableAsync,另一个就是 Async。 12口gcowNuin4-口; -I i3Scheduled(fixcLR.4te-20_000)t.11cvcidtask:4() DareFormatdfnewSimpleDateTomarpartem:yyyy-MM-dd.UH.:mni:ss-); System.cut,printIn(iformat(newDate()4r:+ThEeadcurrentFftread(.ffetNai) longcovNumb-0; gSched

14、uled(fixedRa.tc-20000) p-ji:1XGVQ2.dId号作51)f DmtuF口matdf=0秆SiwleDaeFQiniac(pattern;yyy-HM-dd皿;ma;字号SystemprintIn(d.fformat(newDae()+-p:F,+ThreadcurrentThreadgetNai 首先我们单纯的在方法上引入Async异步注解,并且打印当前线程的名称,实验后发现, 方法仍然是由一个线程来同步执行的。 和$23的上类似还是通过Enable开头的注解来控制执行的。我们在启动类上加入 EnableAsync后再观察输出内容。 2020-03-2209:52

15、:46:Siinp1eAsyncTaskExecutar-2t 赛 sk5 来数牛 0 2020-03-2209:52:46:Sinp1eAsyncTaskEiecutor-1tdskl 来敬牛 0 2020-03-2209:52:58:Sinp1eAsyncTask31ecutor-3t 瓜 sk4 来数牛 1 :Si(p1eAsynclaskiecutor-1 数牛 1 2020-03-2209:53:15:SintpleAsTzicTosliEiecutox-5task1 来数牛 2 2020-03-2209:53:15:Siw1eAsyncTaskEiecutor-6td5k55(5

16、数牛 2 2020-032209:53:35:SiinpleAsyncTaskEiecutor_7task4 来数牛 3 2020-03-2209:53:35:Siinp1eAsyncTaskEzecutor-8 数牛 3 可以发现,默认情况下,其内部是使用的名为SimpleAsyncTaskExecutor的线程池来执行 任务,而且每一次任务调度,都会新建一个线程。 使用EnableAsync注解开启了Spring的异步功能,Spring会按照如下的方式查找相应的线程池用于执行异步方法:查找实现了TaskExecutor接口的Bean实例。 2020-03-2209:52:58 如果还是没有

17、找到,则使用SimpleAsyncTaskExecutor,该实现每次都会创建一个新的线程执行任务。 并发执行任务如何配置? 方式一,我们可以将默认的线程池替换为我们自定义的线程池。通过ScheduleConfig配置文件实现SchedulingConfigurer接口,并重写setSchedulerfang方法。 可实现AsyncConfigurer接口复写getAsyncExecutor获取异步执行器, getAsyncUncaughtExceptionHandler获取异步未捕获异常处理器 ConfigurationpublicclassScheduleConfigimplementsS

18、chedulingConfigurer Override publicvoidconfigureTasks(ScheduledTaskRegistrartaskRegistrar) taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5); 方式二:不改变任务调度器默认使用的线程池,而是把当前任务交给一个异步线程池去执行。 Scheduled(fixedRate=1000*10,initialDelay=1000*20) Async(hyqThreadPoolTaskExecutor) publicvoidtest() System.out.println(Thread.currentThread().getName()+-xxxxx-+Thr ead.currentThread().getId(); /自定义线程池 Bean(name=hyqThreadPoolTaskExecutor) publicTaskExecutorgetMyThreadPoolTaskExecutor() taskExecutor.setCorePoolSize( 20); taskExecutor.setMaxPoolSi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论