理解Spring定时任务@Scheduled的两个属性fixedRate和fixedDelay
fixedRate和fixedDelay都是表示任务执行的间隔时间
fixedRate和fixedDelay的区别:
fixedDelay
非常好理解,它的间隔时间是根据上次的任务结束的时候开始计时的。比如一个方法上设置了fixedDelay=5*1000,那么当该方法某一次执行结束后,开始计算时间,当时间达到5秒,就开始再次执行该方法。
fixedRate
理解起来比较麻烦,它的间隔时间是根据上次任务开始的时候计时的。比如当方法上设置了fiexdRate=5*1000,该执行该方法所花的时间是2秒,那么3秒后就会再次执行该方法。
但是这里有个坑,当任务执行时长超过设置的间隔时长,那会是什么结果呢。打个比方,比如一个任务本来只需要花2秒就能执行完成,我所设置的fixedRate=5*1000,但是因为网络问题导致这个任务花了7秒才执行完成。当任务开始时Spring就会给这个任务计时,5秒钟时候Spring就会再次调用这个任务,可是发现原来的任务还在执行,这个时候第二个任务就阻塞了(这里只考虑单线程的情况下,多线程后面再讲),甚至如果第一个任务花费的时间过长,还可能会使第三第四个任务被阻塞。被阻塞的任务就像排队的人一样,一旦前一个任务没了,它就立马执行。
下面用代码来具体验证一下。
@SpringBootApplication
@EnableScheduling
public class ScheduledemoApplication {private AtomicInteger number = new AtomicInteger();public static void main(String[] args) {SpringApplication.run(ScheduledemoApplication.class, args);}@Scheduled(fixedRate = 5000 )public void job(){LocalTime start = LocalTime.now();//前面和末尾几个字符串是用来改变打印的颜色的System.out.println("\033[31;4m" + Thread.currentThread() + " start " + number.incrementAndGet()+ " @ " + start + "\033[0m");try {Thread.sleep(ThreadLocalRandom.current().nextInt(15)*1000);} catch (InterruptedException e) {e.printStackTrace();}LocalTime end = LocalTime.now();System.out.println(Thread.currentThread() + " end " + number.get() + " @ "+end + ", seconds cost "+ (ChronoUnit.SECONDS.between(start, end)));}}
执行结果如下:
可以看到任务第一次执行完以后还有间隔4秒才执行第二次,可是到了第二次结束的时候,就没有间隔了,直接就执行第三次了。甚至在执行第四次的时候,明明第四次任务只花费了1秒,可还是马上就执行第五次了。因为前面两次任务花费的时间太久了,有好几个被调度的任务都被阻塞了。所以当第四次一结束,马上第五次就执行了。
@Scheduled(fixedRate)如何避免任务被阻塞
答案是加上注解@EnableAsync
(类上)和@Async
(方法上),加了注解以后,就开启了多线程模式,当到了下一次任务的执行时机时,如果上一次任务还没执行完,就会自动创建一个新的线程来执行它。异步执行也可以理解为保证了任务以固定速度执行。
开启多线程后执行结果如下:
可以看到,开启多线程后,每次任务开始的间隔都是5秒钟。这是符合我们预期的,但是最后还有点缺陷,这种情况下的线程是随着任务一执行完就销毁的,等下次有需要了程序再创建一个。每次都要重新创建明显是太影响性能了,所以需要在代码里给他一个线程池。
创建一个线程池
@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();taskScheduler.setPoolSize(5);return taskScheduler;}
可以看到现在程序就不会再自己创建线程了,每次都会从线程池里面拿。需注意的是,如果线程池里的所有线程都被拿去执行调度任务了,且又到了时间要执行一次任务,那么这个任务又会被阻塞。所以实际开发中如果想要保证任务以速度被执行,线程池的最大线程数量可要想好。
话说真的要深入理解的话其实还得看源码,这些测试只是通过表象来猜测。
over
理解Spring定时任务@Scheduled的两个属性fixedRate和fixedDelay相关推荐
- 理解Spring定时任务@Scheduled的两个属性fixedRate和fixedDelay以及固定时间的定时cron
fixedRate和fixedDelay都是表示任务执行的间隔时间 fixedRate和fixedDelay的区别: fixedDelay非常好理解,它的间隔时间是根据上次的任务结束的时候开始计时的. ...
- 【定时任务】——Spring定时任务Scheduled
定时任务在日常开发过程中非常常见,而且在日常的项目开发中也有多种实现方式,而且做任务调度的框架有很多种,小编最近的感受,如果想真正使用好任务调度还是存在困难的,所以分步学习,逐个击破!在这篇文章小编主 ...
- Spring定时任务@Scheduled注解使用配置方式(cron表达式、fixedRate和fixedDelay)
Spring定时任务@Scheduled注解使用配置方式(cron表达式.fixedRate和fixedDelay) 序言: 个人推荐一个很方便的在线Cron生成器(网页版):https://qqe2 ...
- Spring定时任务@scheduled多线程的使用(@Async注解)
1.开篇 在Spring定时任务@Scheduled注解使用方式浅窥这篇文章里面提及过,spring的定时任务默认是单线程的,他在某些场景下会造成堵塞,那么如果我们想让每一个任务都起一条线程去执行呢? ...
- spring定时任务Scheduled与定时任务线程池配置SchedulingConfigurer ,Java
spring定时任务Scheduled与定时任务线程池配置SchedulingConfigurer ,Java spring默认定时任务的使用 package zhangphil.demo;impor ...
- Spring定时任务@Scheduled注解使用方式浅窥(cron表达式、fixedRate和fixedDelay)
1.开篇 spring的@Scheduled定时任务相信大家都是十分熟悉.最近在使用过程中发现了一些问题,写篇文章,和大家分享一下.结论在最后,不想看冗长过程的小伙伴可以直接拉到最后看结论. 2.简单 ...
- Spring定时任务-@Scheduled
目的:使用Spring的@Scheduled实现定时任务 1.在spring的配置文件中加入以下配置: xmlns:task="http://www.springframework.org/ ...
- Spring定时任务scheduled
Spring定时任务 一. cron 表达式 1. 概念:Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: 2. Cro ...
- 理解Spring定时任务的fixedRate和fixedDelay
用过 Spring 的 @EnableScheduling 的都知道,我们用三种形式来部署计划任务,即 @Scheduled 注解的 fixedRate(fixedRateString), fixe ...
最新文章
- java.io与网络通信
- linux 网络错误 nf_conntrack: table full, dropping packet. 路由跟踪表满
- TCP的拥塞控制(详解)
- 算法之组合数学及其算法篇(一) ----- 排列与组合
- aspx练习备忘录#想锤自己两拳#1
- Image inpainting 图像修补最新综述
- GPU Architect Functional Verification
- linux下内存调试工具——valgrind
- 计算机安全权限不足或配置文件损坏,Windows XP用户配置文件丢失或损坏后的恢复方法...
- 重归理性 国内SOA平台期待价值提升
- 小程序外包开发指南:如何开发一款游戏?
- 虚拟现实应用案例_虚拟现实的应用
- Uncode、ASCII、UTF-8之前的转换函数
- 基于hal的hcsr04使用注意事项(f103c8t6)
- 开放数据库:青少年健康主题数据库——国家人口健康科学数据中心
- php代码托管平台,程序员必须知道的几个Git代码托管平台
- 李迟2022年5月工作生活总结
- 直流电机笔记1-串并励电机特性
- rplidar连接计算机显示process has died.....解决方法
- 工业互联网在现阶段给制造业带来什么?