spring定时任务详解springschedule和spring-quartz
2023年7月21日发(作者:)
spring定时任务详解springschedule和spring-quartz从实现的技术上来分类,java定时任务⽬前主要有三种:1. Java⾃带的类,这个类允许你调度⼀个ask任务。使⽤这种⽅式可以让你的程序按照某⼀个频度执⾏,但不能在指定时间运⾏;⽽且作业类需要集成ask,⼀般⽤的较少。2. Quartz,这是⼀个功能⽐较强⼤的的调度器,可以让你的程序在指定时间执⾏,也可以按照某⼀个频度执⾏;使⽤起来需要继承JobBean,配置稍显复杂,所以,⼀般会使⽤spring集成quartz,稍后会详细介绍;3. Spring3.0以后⾃带的task,即:spring schedule,可以将它看成⼀个轻量级的Quartz,⽽且使⽤起来⽐Quartz简单许多。综上,spring中使⽤定时任务有两种⽅式:spring schedule和spring-quartz,接下来我们重点介绍这两种。使⽤前都需要引⼊spring的包。 framework spring-core ${n} jar compile framework spring-beans ${n} jar compile framework spring-context ${n} jar compile framework spring-context-support ${n}spring schedule1、xml配置的⽅式:1):⾸先在中引⼊task的命名空间,以及通过task标签定义任务。 2)任务类:import led;import ent;@Componentpublic class DoSomethingTask { public void doSomething() { n("do something"); }}2、@schedule 注解⽅式:1)同样在中引⼊task的命名空间,以及启⽤注解驱动的定时任务。
2)任务类:import led;import ent;@Componentpublic class DoSomethingTask { @Scheduled(cron="0 * * * * *") public void doSomething() { n("do something"); }}3、Cron表达式:由6~7项组成,中间⽤空格分开。从左到右依次是:秒、分、时、⽇、⽉、周⼏、年(可省略)。值可以是数字,也可以是以下符号:*:所有值都匹配:⽆所谓,不关⼼,通常放在“周⼏”⾥,:或者/:增量值-:区间例如:0 * * * * *:每分钟(当秒为0的时候)0 0 * * * *:每⼩时(当秒和分都为0的时候)*/10 * * * * *:每10秒0 5/15 * * * *:每⼩时的5分、20分、35分、50分0 0 9,13 * * *:每天的9点和13点4、@Scheduled注解的另外两个属性:fixedRate和fixedDelay 1)fixedDelay设置的是:上⼀个任务结束后多久执⾏下⼀个任务; 2)fixedRate设置的是:上⼀个任务的开始到下⼀个任务开始时间的间隔;注:如果是强调任务间隔的定时任务,建议使⽤fixedRate和fixedDelay,如果是强调任务在某时某分某刻执⾏的定时任务,建议使⽤cron表达式。5、并发执⾏1)spring schedule的定时任务默认是单线程的处理⽅式是等待上⼀个任务执⾏完成后,再去执⾏下⼀个任务。(⽆论是cron还是fixedDelay、fixedRate都遵循这个原则)。下⾯举⼀些例⼦:⽰例1:通过cron定时执⾏:任务运⾏时间6s、每5s运⾏⼀次任务//使⽤注解⽅式创建定时任务@Componentpublic class testTask { private Logger logger = ger(); @Scheduled(cron = "0/5 * * * * ?") public void doTask() { (tThread().getName()+"===task run"); (6*1_000); (tThread().getName()+"===task end"); }}//⽇志如下2018-06-11 16:03:00.006 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:03:06.013 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 16:03:10.115 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:03:17.267 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 16:03:20.055 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:03:26.164 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end根据⽇志可以看出,spring schedule默认是单线程处理的,下⼀个任务会等上⼀个运⾏完再执⾏。⽰例2:换成fixedDelay@Scheduled(fixedDelay = 5*1_000)public void doTask() throws InterruptedException { (tThread().getName()+"===task run"); (6*1_000); (tThread().getName()+"===task end");}//⽇志如下:2018-06-11 16:31:08.122 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:31:14.139 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 16:31:19.149 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:31:25.261 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 16:31:30.269 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:31:36.385 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end从⽇志可以看出,任务结束时间再经过5s开始再次运⾏。⽰例3:fixedRate@Scheduled(fixedRate = 5*1_000)public void doTask() throws InterruptedException { (tThread().getName()+"===task run"); (6*1_000); (tThread().getName()+"===task end");}//⽇志2018-06-11 16:54:36.118 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:54:42.580 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 16:54:42.607 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:54:48.632 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 16:54:48.639 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 16:54:55.188 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end从⽇志可以看出,上⼀个任务结束后,下⼀个任务⽴刻开始执⾏了,因为:fixedRate设置的上⼀个任务的开始时间到下⼀个任务开始时间的间隔。⽰例4:fixedRate上⾯例⼦,运⾏时间从6s改成2s,⽇志如下:2018-06-11 17:08:43.086 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 17:08:45.093 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 17:08:48.025 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 17:08:50.083 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end2018-06-11 17:08:53.239 [pool-12-thread-1] INFO sk -pool-12-thread-1===task run2018-06-11 17:08:55.245 [pool-12-thread-1] INFO sk -pool-12-thread-1===task end结果和我们推断的⼀致,两个任务的开始时间间隔是5s。2)配置并⾏处理上⾯的例⼦是同⼀个task,如果前⼀个还没跑完后⾯⼀个就不会触发,这没有太⼤问题。但是,假设系统中有多个task,默认springschedule是单线程的,就会造成不同的task也不能同时运⾏,就不太合理了。解决⽅法:⽅法⼀:配置多个线程,但这样会导致同⼀个task前⼀个还没跑完后⾯⼜被触发的问题。⽅法⼆:让任务分别运⾏在不同的scheduler⾥
spring-quartzmaven中需要引⼊:、。⽰例:1)定义任务类:(spring集成的quartz不需要集成任何类)@Servicepublic class QuartzTest { public void test(){ n("It's time to run :" + new Date().toString()); //TODO 执⾏任务逻辑 //........ }}2)配置:a)SimpleTrigger⽅式:
b)CronTrigger⽅式:
0 */1 * * * ? 最后,在spring主配置⽂件中把上⾯的 包含进去即可。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1689931526a295303.html
评论列表(0条)