Spring提供的三种定时任务机制及其比较
spring定时任务详解(@Scheduled注解)

spring定时任务详解(@Scheduled注解)Spring配置⽂件xmlns加⼊xmlns:task="/schema/task"xsi:schemaLocation中加⼊/schema/task/schema/task/spring-task-3.0.xsd"Spring扫描注解的配置<context:component-scan base-package="com.imwoniu.*" />任务扫描注解<task:executor id="executor" pool-size="5" /><task:scheduler id="scheduler" pool-size="10" /><task:annotation-driven executor="executor" scheduler="scheduler" />代码实现:注解@Scheduled 可以作为⼀个触发源添加到⼀个⽅法中,例如,以下的⽅法将以⼀个固定延迟时间5秒钟调⽤⼀次执⾏,这个周期是以上⼀个调⽤任务的完成时间为基准,在上⼀个任务完成之后,5s后再次执⾏:@Scheduled(fixedDelay = 5000)public void doSomething() {// something that should execute periodically}如果需要以固定速率执⾏,只要将注解中指定的属性名称改成fixedRate即可,以下⽅法将以⼀个固定速率5s来调⽤⼀次执⾏,这个周期是以上⼀个任务开始时间为基准,从上⼀任务开始执⾏后5s再次调⽤:@Scheduled(fixedRate = 5000)public void doSomething() {// something that should execute periodically}如果简单的定期调度不能满⾜,那么cron表达式提供了可能package com.imwoniu.task;import org.springframework.scheduling.annotation.Scheduled;import ponent;@Componentpublic class TaskDemo {@Scheduled(cron = "0 0 2 * * ?") //每天凌晨两点执⾏void doSomethingWith(){("定时任务开始......");long begin = System.currentTimeMillis();//执⾏数据库操作了哦...long end = System.currentTimeMillis();("定时任务结束,共耗时:[" + (end-begin) / 1000 + "]秒");}}关于Cron表达式(转载)表达式⽹站⽣成:按顺序依次为秒(0~59)分钟(0~59)⼩时(0~23)天(⽉)(0~31,但是你需要考虑你⽉的天数)⽉(0~11)天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)7.年份(1970-2099)其中每个元素可以是⼀个值(如6),⼀个连续区间(9-12),⼀个间隔时间(8-18/4)(/表⽰每隔4⼩时),⼀个列表(1,3,5),通配符。
SpringBoot之旅--定时任务两种(SpringSchedule与Quartz整合)实现

SpringBoot之旅--定时任务两种(SpringSchedule与Quartz整合)实现相关⽂章前⾔最近在项⽬中使⽤到定时任务,之前⼀直都是使⽤Quartz 来实现,最近看Spring 基础发现其实Spring 提供 Spring Schedule 可以帮助我们实现简单的定时任务功能。
下⾯说⼀下两种⽅式在Spring Boot 项⽬中的使⽤。
Spring Schedule 实现定时任务Spring Schedule 实现定时任务有两种⽅式 1. 使⽤XML配置定时任务, 2. 使⽤ @Scheduled 注解。
因为是Spring Boot 项⽬可能尽量避免使⽤XML配置的形式,主要说注解的形式.Spring Schedule 提供三种形式的定时任务:固定等待时间 @Scheduled(fixedDelay = 时间间隔 )@Componentpublic class ScheduleJobs {public final static long SECOND = 1 * 1000;FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");@Scheduled(fixedDelay = SECOND * 2)public void fixedDelayJob() throws InterruptedException {TimeUnit.SECONDS.sleep(2);System.out.println("[FixedDelayJob Execute]"+fdf.format(new Date()));}}固定间隔时间 @Scheduled(fixedRate = 时间间隔 )@Componentpublic class ScheduleJobs {public final static long SECOND = 1 * 1000;FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");@Scheduled(fixedRate = SECOND * 4)public void fixedRateJob() {System.out.println("[FixedRateJob Execute]"+fdf.format(new Date()));}}Corn表达式 @Scheduled(cron = Corn表达式)@Componentpublic class ScheduleJobs {public final static long SECOND = 1 * 1000;FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");@Scheduled(cron = "0/4 * * * * ?")public void cronJob() {System.out.println("[CronJob Execute]"+fdf.format(new Date()));}}Spring Boot 整合 Quartz 实现定时任务添加Maven依赖<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency>Spring Boot 整合 QuartzSpring 项⽬整合 Quartz 主要依靠添加 SchedulerFactoryBean 这个 FactoryBean ,所以在maven 依赖中添加 spring-context-support 。
spring的@Scheduled定时任务,同一时间段的定时任务只会执行一个,其余的会被阻。。。

spring的@Scheduled定时任务,同⼀时间段的定时任务只会执⾏⼀个,其余的会被阻。
现有两个定时任务@Component("aa")public class aa {@Scheduled(cron = "0 44 17 * * ?")public void bb() {try {System.out.println("aa执⾏时间:" + new Date());Thread.sleep(65000);System.out.println("aa完成时间:" + new Date());} catch (Exception e) {e.printStackTrace();}}}@Component("bb")public class bb {@Scheduled(cron = "0 55 17 * * ?")public void aa() {try {System.out.println("bb执⾏时间:" + new Date());Thread.sleep(10000);System.out.println("bb完成时间:" + new Date());} catch (Exception e) {e.printStackTrace();}}}默认的在启动项加⼊@EnableScheduling注解就可以运⾏了最终,执⾏的结果令⼈⼤跌眼镜。
aa的任务由于执⾏时间需要65秒,超过了bb任务执⾏的时间,结果bb任务执⾏的时间被阻塞掉,延迟了5秒执⾏。
解决⽅法是在启动项类中加⼊如下配置即可@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();taskScheduler.setPoolSize(50);return taskScheduler;}如果是xml<!-- 注解式 --><task:annotation-driven executor="myExecutor" scheduler="myScheduler"/><task:executor id="myExecutor" pool-size="5"/><task:scheduler id="myScheduler" pool-size="10"/>。
spring定时任务配置

定时任务解决方案两种方案,基本上都是一样,就是配置时间规则的时候,不一致。
两种方案:CronTrigger基于日历和时间,SimpleTrigger基于时间。
方案一是CronTrigger 配置,方案二是SimpleTrigger配置。
Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。
Quartz 允许开发人员根据时间间隔(或天)来调度作业。
它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。
整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。
SimpleTrigger当需要在规定的时间执行一次或在规定的时间段以一定的时间间隔重复触发执行Job时,SimpleTrigger就可以满足要求;SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔,重复次数属性的值可以为0、正整数、或常量 SimpleTrigger.REPEAT_INDEFINITELY,重复的时间间隔属性值必须为0或长整型的正整数,以毫秒作为时间单位,当重复的时间间隔为0时,意味着与Trigger 同时触发执行(或几乎与Scheduler开始时同时触发执行)。
如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒钟触发一次直到指定的结束时间的 Trigger,而无需去计算从开始到结束的所重复的次数,我们只需简单的指定结束时间和使用REPEAT_INDEFINITELY作为重复次数的属性值即可(我们也可以指定一个比在指定结束时间到达时实际执行次数大的重复次数)。
方案一先写一个业务类,然后进行如下配置,一步都不能少,这样就能完成一个定时任务。
第一步写一个业务类这个业务很简单,不需要实现任务spring的接口。
就是一个普通业务类,然后写一个业务方法。
到时候配置定时任务,就会定时的执行这个业务方法。
JAVA:定时器的三种方法(详细注解)

JAVA:定时器的三种⽅法(详细注解)在Java中为我们提供了Timer来实现定时任务,当然现在还有很多定时任务框架,⽐如说Spring、QuartZ、Linux Cron等等,⽽且性能也更加优越。
但是我们想要深⼊的学习就必须先从最简单的开始。
第⼀种:创建⼀个thread,然后让它在while循环⾥⼀直运⾏着,通过sleep⽅法来达到定时任务的效果,代码如下public class Task1 {public static void main(String[] args) {// run in a second// 每⼀秒钟执⾏⼀次final long timeInterval = 1000;Runnable runnable = new Runnable() {public void run() {while (true) {// ------- code for task to run// ------- 要运⾏的任务代码System.out.println("Hello, stranger");// ------- ends heretry {// sleep():同步延迟数据,并且会阻塞线程Thread.sleep(timeInterval);} catch (InterruptedException e) {e.printStackTrace();}}}};//创建定时器Thread thread = new Thread(runnable);//开始执⾏thread.start();}}第⼆种:启动和去取消任务时可以控制,可以指定你想要的delay(开始执⾏的等待时间)时间,在实现时,Timer类可以调度任务,TimerTask 则是通过在run()⽅法⾥实现具体任务。
Timer实例可以调度多任务,它是线程安全的。
当Timer的构造器被调⽤时,它创建了⼀个线程,这个线程可以⽤来调度任务。
java中实现定时任务的常用方式,以及差异和注意事项。

java中实现定时任务的常用方式,以及差异和注意事项。
1 Java中实现定时任务的常用方式在Java中,实现定时任务的方式很多,以下是目前比较常用的几种方式:1.1 Timer和TimerTaskTimer和TimerTask是Java中自带的定时任务实现方式。
Timer 是一个定时器类,支持在指定时间后执行任务,并且支持延迟和定时重复执行任务。
TimerTask则是一个实现了Runnable接口的抽象类,通过继承TimerTask并实现run()方法来定义具体的任务。
1.2 ScheduledExecutorServiceScheduledExecutorService是Java中提供的一种用于执行定时任务的线程池。
与Timer和TimerTask相比,ScheduledExecutorService的在线程安全性、定时任务的精度、定时任务的灵活性等方面有很大的改进。
ScheduledExecutorService支持延迟和定时重复执行任务,并且可以控制定时任务的执行周期、并发性等。
1.3 Spring中的@ScheduledSpring框架中提供了@Scheduled注解来支持定时任务的实现。
通过在指定的方法上加上@Scheduled注解,指定定时任务的执行周期和策略,就可以很方便地实现定时任务。
@Scheduled注解的实现依赖于ScheduledExecutorService。
1.4 Quartz框架Quartz是一个高效、灵活、可靠的开源定时任务调度框架,它提供了大量的功能和扩展点,并且可以与Spring等框架集成使用。
使用Quartz框架可以非常方便地实现复杂的定时任务逻辑,比如任务调度的优先级、任务的依赖关系、任务的失败重试等。
2. 差异与注意事项不同的定时任务实现方式在功能和特性上有差异,因此在选择合适的定时任务实现方式时需要考虑以下几点:2.1 精度和性能不同的定时任务实现方式在任务执行的精度和性能上有差异。
Spring@Scheduled定时任务的fixedRate,fixedDelay,cro。。。

Spring@Scheduled定时任务的fixedRate,fixedDelay,cro。
⼀. 三种定时类型。
1.cron --@Scheduled(cron="0/5 * * * *?")当时间达到设置的时间会触发事件。
上⾯那个例⼦会每5秒执⾏⼀次。
2018/1/4 14:27:302018/1/4 14:27:352018/1/4 14:27:402018/1/4 14:27:452018/1/4 14:27:502.fixedRate --@Scheduled(fixedRate=2000)每两秒执⾏⼀次时间。
3.fixedDelay --@Scheduled(fixedDelay=2000)每次任务执⾏完之后的2s后继续执⾏看字⾯意思容易理解,但是任务执⾏长度超过周期会怎样呢?不多说,直接上图:import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import org.springframework.scheduling.annotation.Scheduled;import ponent;@Componentpublic class MyProcessor{DateFormat sdf = new SimpleDateFormat("HH:mm:ss");int[] delays = new int[]{8,3,6,2,2};int index = 0;@Scheduled(cron = "0/5 * * * * ?}")public void process() {try {if(index > delays.length - 1){if(index == delays.length){System.out.println("---------- test end at " + sdf.format(new Date()) + " ---------");}index ++;return;}else{System.out.println(index + ":start run at" + sdf.format(new Date()));}Thread.sleep(delays[index] * 1000);System.out.println(index + ":end run at " + sdf.format(new Date()));index ++;} catch (InterruptedException e) {e.printStackTrace();}}}。
Spring@EnableScheduling定时任务用法总结

Spring@EnableScheduling定时任务用法总结1. 原理1.1 TaskSchedulerTaskScheduler是spring的定时任务使用的线程池的关键类public interface TaskScheduler {// 通过Trigger执行任务ScheduledFuture schedule(Runnable task, Trigger trigger);// 指定时间执行任务ScheduledFuture schedule(Runnable task, Date startTime);// 指定在指定时间后,循环周期执行任务ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);// 循环周期执行任务ScheduledFuture scheduleAtFixedRate(Runnable task, long period);// 延迟N时间,在指定日期执行ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);}•1•2•3•4•5•6•7•8•9•10•11•12•13•14•1•2•3•4•5•6•7•8•9•10•11•12•13•14TaskScheduler有两种实现方式:- TimerManagerTaskScheduler:使用外部对象管理线程池,如CommonJ TimerManager,适用于多个进程共享线程池- ThreadPoolTaskScheduler:如果仅仅在同一进程管理线程池,则推荐使用此对象。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Spring提供的三种定时任务机制及其比较定时任务的需求在众多应用系统中广泛存在,在Spring中,我们可以使用三种不同的定时机制,下面一一描述并加以比较1. 基于Quartz的定时机制下面详细解释这个类图中涉及的关键类及其使用场景1.1. SchedulerFactoryBean这是Spring中基于Quartz的定时机制入口,只要Spring容器装载了这个类,Quartz定时机制就会启动,并加载定义在这个类中的所有triggerSpring配置范例:[xhtml]view plaincopy1.<bean id="sfb"class="org.springframework.scheduling.quartz.SchedulerFactoryBean">2.<!-- 添加触发器 -->3.<property name="triggers">4.<list>5.<ref local="appSubscTrigger"/>6.</list>7.</property>8.9.<!-- 添加listener -->10.<property name="globalTriggerListeners">11.<list>12.<ref local="myTaskTriggerListener"/>13.</list>14.</property>15.</bean>1.2. CronTriggerBean实现了Trigger接口,基于Cron表达式的触发器这种触发器的好处是表达式与linux下的crontab一致,能够满足非常复杂的定时需求,也容易配置Spring配置范例:[xhtml]view plaincopy1.<bean id="notifyTrigger"class="org.springframework.scheduling.quartz.CronTriggerBean">2.<property name="jobDetail"ref="notifyJobDetail"/>3.<property name="cronExpression"value="${notify_trigger_cron_expression}"/>4.</bean>1.3. SimpleTriggerBean该类也实现了Trigger接口,基于配置的定时调度这个触发器的优点在于很容易配置一个简单的定时调度策略Spring配置范例:[xhtml]view plaincopy1.<bean id="simpleReportTrigger"class="org.springframework.scheduling.quartz.SimpleTriggerBean">2.<property name="jobDetail">3.<ref bean="reportJob"/>4.</property>5.<property name="startDelay">6.<value>3600000</value>7.</property>8.<property name="repeatInterval">9.<value>86400000</value>10.</property>11.</bean>1.4. JobDetailBeanJobDetail类的简单扩展,能够包装一个继承自QuartzJobBean的普通Bean,使之成为定时运行的Job缺点是包装的Bean必须继承自一个指定的类,通用性不强,对普通Job的侵入性过强,不推荐使用1.5. MethodInvokingJobDetailFactoryBeanSpring提供的一个不错的JobDetail包装工具,能够包装任何bean,并执行类中指定的任何stati或非static的方法,避免强制要求bean去实现某接口或继承某基础类Spring配置范例:[xhtml]view plaincopy1.<bean id="notifyJobDetail"parent="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">2.<property name="targetObject"ref="notifyServerHandler"/>3.<property name="targetMethod"value="execute"/>4.</bean>1.6. 关于TriggerListener和JobListenerQuartz中提供了类似WebWork的拦截器的功能,系统执行任务前或任务执行完毕后,都会检查是否有对应的Listener需要被执行,这种AOP的思想为我们带来了灵活的业务需求实现方式。
例如现在有一个简单的业务要求:任务执行前先判断当前服务器是否为task服务器,不是则不执行任务。
对于这种业务需求,我们可以简单的实现一个TriggerListener,并将其插入SchedulerFactoryBean的globalTriggerListeners中,这样所有的job在执行前后都会调用TriggerListener中对应的方法。
代码范例:[java]view plaincopy1.public class MyTaskTriggerListener implements TriggerListener {2.protected static final Log logger = LogFactory.getLog(MyTaskTriggerListener.class);3.4./**5. * 需要运行task任务的机器列表6. */7.private String taskServers;8.9.public String getName() {10.return"MyTaskTriggerListener";11. }12.13.public void triggerComplete(Trigger arg0, JobExecutionContext arg1, intarg2) {14. }15.16.public void triggerFired(Trigger arg0, JobExecutionContext arg1) {17. }18.19.public void triggerMisfired(Trigger arg0) {20. }21.22./**23. * 判断当前服务器是否为task服务器,来决定是否执行task24. * @return25. */26.public boolean vetoJobExecution(Trigger arg0, JobExecutionContext arg1){27. String serverName;28.try {29. serverName = InetAddress.getLocalHost().getHostName();//获取主机名30. } catch (UnknownHostException e) {31. e.printStackTrace();32.return true;33. }34.if (taskServers.indexOf(serverName) > -1) {35.if (logger.isInfoEnabled()) {36. ("this is a task server, job will be executed");37. }38.return false;39. } else {40.if (logger.isInfoEnabled()) {41. ("this is not a task server, job will be vetoed");42. }43.return true;44. }45. }46.47.public String getTaskServers() {48.return taskServers;49. }50.51.public void setTaskServers(String taskServers) {52.this.taskServers = taskServers;53. }54.}2. 基于Timer的定时机制JDK提供了基础的定时类:Timer,在这个类的基础上,Spring提供了一套简单的定时机制下面详细解释这个类图中涉及的关键类及其使用场景2.1. TimerFactoryBean这个类非常类似Quartz中的SchedulerFactoryBean,是基于Timer的定时机制的入口,Spring容器装载此类后会自动开始定时器Spring配置范例:[xhtml]view plaincopy1.<bean id="timerFactory"class="org.springframework.scheduling.timer.TimerFactoryBean">2.<property name="scheduledTimerTasks">3.<list>4.<ref bean="scheduledTask"/>5.</list>6.</property>7.</bean>2.2. ScheduledTimerTask类似于Quartz中的Trigger的SimpleTriggerBean实现,任务是在设定的时间触发并执行配置的任务,特点是配置简单、明了,使用于简单的任务触发逻辑Spring配置范例:[xhtml]view plaincopy1.<bean id=”scheduledReportTask”class=”org.springframework.scheduling.timer.ScheduledTimerTask”>2.<property name=”timerTask”>3.<ref bean=”reportTimerTask”/>4.</property>5.<property name=”period”>6.<value>86400000</value>7.</property>8.</bean>2.3. TimerTask抽象类普通task实现必须要继承的父类,主要包含一个run()的方法,类似Quartz中的QuartzJobBean,对应用侵入性较强,也不推荐使用2.4. MethodInvokingTimerTaskFactoryBean类似Quartz中的MethodInvokingJobDetailFactoryBean,用于封装任何bean,并可以执行bean中的任意方法,不再复述3. 基于Executor的定时机制这种定时机制与上面两种定时机制没有太大区别,特别是在配置和实现功能上,不同的是它的核心是基于ScheduledExecutorService(ScheduledThreadPoolExecutor是默认实现),一种JDK5.0中提供的基于线程的并发机制,关于JDK5中的线程池的概念及其一些深入分析,请参考老唐的博客:/sfdev/archive/2008/12/30/3648457.aspx这里不再复述4. 三种定时机制的比较和案例分析看完了这三种定时机制,各有各的优劣,不同场景下我们应该灵活选择不同的定时机制。