理解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秒钟。这是符合我们预期的,但是最后还有点缺陷,这种情况下的线程是随着任务一执行完就销毁的,等下次有需要了程序再创建一个。每次都要重新创建明显是太影响性能了,所以需要在代码里给他一个线程池。
创建一个线程池
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(5);
return taskScheduler;
}

可以看到现在程序就不会再自己创建线程了,每次都会从线程池里面拿。需注意的是,如果线程池里的所有线程都被拿去执行调度任务了,且又到了时间要执行一次任务,那么这个任务又会被阻塞。所以实际开发中如果想要保证任务以速度被执行,线程池的最大线程数量可要想好。
话说真的要深入理解的话其实还得看源码,这些测试只是通过表象来猜测。
over
理解Spring定时任务@Scheduled的两个属性fixedRate和fixedDelay的更多相关文章
- Spring 定时任务Scheduled 开发详细图文
Spring 定时任务Scheduled 开发 文章目录 一.前言 1.1 定时任务 1.2 开发环境 1.3 技术实现 二.创建包含WEB.xml 的Maven 项目 2.1 创建多模块项目task ...
- spring 定时任务@Scheduled
1.配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:/ ...
- Spring定时任务@Scheduled注解使用方式
1.开篇 spring的@Scheduled定时任务相信大家都是十分熟悉.最近在使用过程中发现了一些问题,写篇文章,和大家分享一下.结论在最后,不想看冗长过程的小伙伴可以直接拉到最后看结论. 2.简单 ...
- Spring定时任务(@Scheduled)
一.使用Spring的@Scheduled实现定时任务[1] 1.Spring配置文件xmlns加入 xmlns:task="http://www.springframework.org/s ...
- 通过源码理解Spring中@Scheduled的实现原理并且实现调度任务动态装载
前提 最近的新项目和数据同步相关,有定时调度的需求.之前一直有使用过Quartz.XXL-Job.Easy Scheduler等调度框架,后来越发觉得这些框架太重量级了,于是想到了Spring内置的S ...
- 理解Spring定时任务的fixedRate和fixedDelay
用过 Spring 的 @EnableScheduling 的都知道,我们用三种形式来部署计划任务,即 @Scheduled 注解的 fixedRate(fixedRateString), fixe ...
- 理解 Spring 定时任务的 fixedRate 和 fixedDelay 的区别
用过 Spring 的 @EnableScheduling 的都知道,有三种方式,即 @Scheduled 注解的 fixedRate(fixedRateString), fixedDelay(fix ...
- spring 定时任务 scheduled Cron表达式
转载:https://blog.csdn.net/u011789653/article/details/51153536 可以借鉴:https://www.cnblogs.com/softidea/p ...
- spring定时任务注解@Scheduled的记录
spring 定时任务@Scheduled 转自https://www.cnblogs.com/0201zcr/p/5995779.html 1.配置文件 <?xml version=" ...
随机推荐
- 快速了解MongoDB
简介 MongoDB是一款为广泛的现代应用程序设计的高性能.可扩展.分布式数据库系统.MongoDB可用于不同规模大小的组织,为那些对系统低延迟.高吞吐量以及可持续性有很高要求的应用提供稳定关键的服务 ...
- 【Spring Boot】Spring Boot之利用Logstash将日志转换成以JSON的格式存储和输出
一.Logstash的作用 Logstash是一个完全开源的工具,它可以对日志进行收集.过滤,能非常方便地将日志转换成以JSON的格式存储和输出,并将其存储供以后使用. 二.整合Logstash的步骤 ...
- Linux服务器性能分析与优化
影响服务器性能的因素: CPU :大部分cpu在同一时间只能运行一个线程,超线程的处理器可以在同一时间处理多个线程,因此可以利用超线程特性提高系统性能. 在linux系统下,只有运行SMP内核才能支持 ...
- vue.js生成纵向拓扑图
1.前端代码 <link href="https://magicbox.bk.tencent.com/static_api/v3/assets/bootstrap-3.3.4/css/ ...
- centos服务器上线第二个django项目方法。
阿里云服务器开启端口8001,9001 创建一个虚拟环境 virtualenv -p python3 web2 使虚拟环境生效 source web2/bin/activate 虚拟环境中安装djan ...
- 浅谈JS之Error对象
[前言] 本文主要介绍下JS的Error name相关属性. 当 JS 引擎执行 JS代码时,会发生各种错误. ①语法错误,通常是程序员造成的编码错误或错别字: ②拼写错误或语言中缺少的功能(可能 ...
- 【比赛游记】(THUPC,CTS,APIO)2019四连爆蛋记
5 月 11 日 坐飞机来到帝都,报道 THUPC. 试机题有皮配,不会. 晚上吃全聚德,喝星巴克.奢侈. 5 月 12 日 早上打 THUPC. 咕到 9 点半开始,到 2 点半结束.
- scala简单的功能实现~weektwo
1.编写⼀个BankAccount类,假如deposit和withdraw⽅法,和⼀个只读的balance属性. //存款(deposit)和取款()函数 class BankAccount exte ...
- 教你如何解决WIN 10系统睡眠无法唤醒
1.右击“开始菜单”,选择“电源选项”. 2.选择“更改计算机睡眠时间”. 3.选择“更改高级电源设置”. 4.选择“还原计划默认值”. 5.在弹出的对话框中选择“是 ”. 6.最后选 ...
- python文件读取,替换(带格式,python lib 库)
import os, time import sys import re def read_old_part(filename, start, end): content = [] recording ...