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的更多相关文章

  1. Spring 定时任务Scheduled 开发详细图文

    Spring 定时任务Scheduled 开发 文章目录 一.前言 1.1 定时任务 1.2 开发环境 1.3 技术实现 二.创建包含WEB.xml 的Maven 项目 2.1 创建多模块项目task ...

  2. spring 定时任务@Scheduled

    1.配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:/ ...

  3. Spring定时任务@Scheduled注解使用方式

    1.开篇 spring的@Scheduled定时任务相信大家都是十分熟悉.最近在使用过程中发现了一些问题,写篇文章,和大家分享一下.结论在最后,不想看冗长过程的小伙伴可以直接拉到最后看结论. 2.简单 ...

  4. Spring定时任务(@Scheduled)

    一.使用Spring的@Scheduled实现定时任务[1] 1.Spring配置文件xmlns加入 xmlns:task="http://www.springframework.org/s ...

  5. 通过源码理解Spring中@Scheduled的实现原理并且实现调度任务动态装载

    前提 最近的新项目和数据同步相关,有定时调度的需求.之前一直有使用过Quartz.XXL-Job.Easy Scheduler等调度框架,后来越发觉得这些框架太重量级了,于是想到了Spring内置的S ...

  6. 理解Spring定时任务的fixedRate和fixedDelay

    用过  Spring 的 @EnableScheduling 的都知道,我们用三种形式来部署计划任务,即 @Scheduled 注解的 fixedRate(fixedRateString), fixe ...

  7. 理解 Spring 定时任务的 fixedRate 和 fixedDelay 的区别

    用过 Spring 的 @EnableScheduling 的都知道,有三种方式,即 @Scheduled 注解的 fixedRate(fixedRateString), fixedDelay(fix ...

  8. spring 定时任务 scheduled Cron表达式

    转载:https://blog.csdn.net/u011789653/article/details/51153536 可以借鉴:https://www.cnblogs.com/softidea/p ...

  9. spring定时任务注解@Scheduled的记录

    spring 定时任务@Scheduled 转自https://www.cnblogs.com/0201zcr/p/5995779.html 1.配置文件 <?xml version=" ...

随机推荐

  1. TP5.0使用助手函数model出现\common\Model\类不存在

    在ThinkPHP5.0中有一个助手助手函数model(),可以实例化具体的模型,包括分层模型,只要传入类名(第一个参数),分层名(第二个参数).这个函数其实是ThinkPHP框架Loader中的一个 ...

  2. set_lb

    修改lb权重,通知钉钉 前提需要安装阿里的核心库 #!/usr/local/python-3.6.4/bin/python3 #coding=utf-8 from aliyunsdkcore.clie ...

  3. C# 获取指定类型的文件

    C# 获取指定类型的文件 public static List<FileInfo> getFile(string path, string extName) { List<FileI ...

  4. likely和unlikely是如何对代码的优化?

             在执行if判断时,可以使用GCC提供了__builtin_expect对代码进行优化,可以提高代码的运行速度,参考GCC手册的"3.10 Options That Cont ...

  5. zabbix--自动注册

    Active agent自动注册 agent 自动注册就是实现一台新的服务器配置好 agent 端,自动在服务器端注册,无需在服务器上进行手动配置便可以直接启动对新的host的监控. 参考官档:htt ...

  6. PAT 乙级 1020.月饼 C++/Java

    题目来源 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部 ...

  7. Android PKMS服务

    它的作用? 关于PKMS的全称是啥应该咱们不陌生,PackageManagerService,和AMS一样是Android系统的核心服务,它主要负责系统中Package的管理,应用程序的安装.卸载.信 ...

  8. 前端模板引擎artTemplate.js

    . 关于artTemplate模板引擎的详细原理请移步高性能JavaScript模板引擎原理解析,本文只探讨如何使用.初学前端的人一般对于绑定数据都是使用原生js或者jquery来拼接字符串,此为ha ...

  9. discuz网站前端代码优化思路

    一.head标签中的局部 1.URL设计 URL尽量含有通用已成趋向的移动命名,例如“m./wap./3g./mobi./mobile./mob/wml/”,能够在子域名等方面表现 2.页面顶部的do ...

  10. 搭建unity客户端

    1.新建个unity的项目ChatClient 2.在unity的Main Camera下挂载个脚本PhotonServerEngine做为与服务器端通信的脚本 3.在PhotonServerEngi ...