Springboot使用定时任务scheduler详解

2023-05-16

目录

  • 认识
  • 示例代码
  • 定时任务 / 调度任务
    • 开启调度
    • 添加定时任务
      • 以固定延迟执行定时任务--fixedDelay
      • 以固定速率执行定时任务--fixedRate
      • 延迟第一次初始化--initialDelay
      • 以 ISO 时间格式指定间隔--fixedRateString
      • 使用 Cron 表达式定义间隔
  • 结论

认识

能够让我们在指定的某个时间段自动执行任务,不需要自己去手动触发。
如:定时发送邮件、定时发送优惠卷等…

示例代码

文章中的代码,保存在Gitee中

定时任务 / 调度任务

开启调度

  • 默认情况下不开启定时任务,如果想使用添加@EnableScheduling来显示启动

    @SpringBootApplication
    @EnableScheduling
    public class SpringSchedulerApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringSchedulerApplication.class, args);
        }
    }
    
  • 更好的做法,是定义一个定时器的配置类,在结合@ConditionalOnProperty控制定时任务的开启和关闭

    @Configuration
    @EnableScheduling
    // 默认为false, 配置为true代表开启定时功能, 
    @ConditionalOnProperty(name = "scheduler.enabled", matchIfMissing = true) 
    public class SchedulerConfig {
    }
    
    

添加定时任务

默认单位都为毫秒(ms)

以固定延迟执行定时任务–fixedDelay

  • fixedDelay属性配置定时任务在指定延迟时间后执行

  • 新任务要等待前一个任务完成,示例如下:

    @Scheduled(fixedDelay = 2000)
    public void computePrice() throws InterruptedException {
      log.info("current time: {}", LocalTime.now());
      Thread.sleep(4000);
    }
    
    • 每2秒执行一次

    • 在新任务开启前, 需要等待旧任务完成。因此我们可以看到6秒后才会执行下一个任务

以固定速率执行定时任务–fixedRate

  • fixedRate属性配置定时任务以固定时间执行定时任务,示例如下:

    @Scheduled(fixedRate = 3000)
    public void refreshPricingParameters() throws InterruptedException {
      log.info("current time: {}", LocalTime.now());
      Thread.sleep(6000);
    }
    
    • 在这里,我们通过设置fixedRate为3000毫秒,使refreshPricingParameters方法每隔3秒就会执行一次。

    • 但是由于Scheduled默认是单线程,导致打印时间为6秒间隔(Thread.sleep(6000))

    • 如果想不被前一个任务的影响,可以通过下面两种方法解决:

      1. 通过开启异步任务

        @Configuration
        @EnableScheduling
        @EnableAsync // 开启异步任务
        @ConditionalOnProperty(name = "scheduler.enabled", matchIfMissing = true) 
        public class SchedulerConfig {
        }
        
        @Scheduled(fixedRate = 3000)
        @Async // 异步执行
        public void refreshPricingParameters() throws InterruptedException {
          log.info("current time: {}", LocalTime.now());
          Thread.sleep(6000);
        }
        
      2. 定时器默认不并行执行是因为线程池默认大小为1,可以通过配置**spring.task.scheduling.pool.size**调整线程池大小。

延迟第一次初始化–initialDelay

  • 使用fixedRatefixedDelay属性,方法的第一次调用,会在上下文初始化完成后通过指定的时间进行调度。

  • 但是可以通过initialDelay 属性,指定第一次方法执行的延迟时间。示例如下:

    // 第一次延迟5秒后执行, 后续延迟都为3秒
    @Scheduled(initialDelay = 5000, fixedRate = 3000)
    @Async
    public void refreshPricingParametersTemp() {
      log.info("current time: {}", LocalTime.now());
    }
    
    • 在这里,将方法第一次执行延迟时间设置为5秒

以 ISO 时间格式指定间隔–fixedRateString

  • 可以通过这个文档ISO-文档了解ISO时间格式,示例如下:

    @Scheduled(fixedDelayString = "PT02S")
    public void computePrice_TEMP() throws InterruptedException {
      log.info("current time: {}", LocalTime.now());
      Thread.sleep(4000);
    }
    
    • 在这里,设置fixedDelayString值为PT02S,表示调用之间以 2 秒的固定延迟执行。
  • 除此之外,fixedDelayString还支持读取配置文件进行设置,示例如下:

    @Scheduled(fixedDelayString = "${interval}")
    public void computePriceTemp() throws InterruptedException {
      log.info("current time: {}", LocalTime.now());
      Thread.sleep(4000);
    }
    
    // yaml设置
    interval: PT02S
    // properties设置
    interval=PT02S
    

使用 Cron 表达式定义间隔

  • cron表达式,用于设置更加复杂的时间。示例如下:

    @Scheduled(cron = "0/2 * * * * ?")
    public String computePrice() throws InterruptedException {
      log.info("current time: {}", LocalTime.now());
      return "";
    }
    
    • 在这里,指定cron0/2 * * * * ?,表示每间隔2秒进行执行
    • 注:cron支持读取配置文件
  • cron表达式格式,我们可以参考Spring官方的调度示例进行学习

    ┌────────────── 秒 (0-59)
     │ ┌───────────── 分钟 (0 - 59)
     │ │ ┌───────────── 小时 (0 - 23)
     │ │ │ ┌───────────── 一个月中的某天 (1 - 31)
     │ │ │ │ ┌───────────── 月(1-12)(或JAN-DEC)
     │ │ │ │ │ ┌───────────── 星期几(0 - 7)
     │ │ │ │ │ │ (0 或 7 为星期日,或 MON-SUN)
     │ │ │ │ │ │
     * * * * * *
    

结论

  • Scheduler调度是核心模块,不需要添加其他依赖
  • 默认情况下不开启调度,需要使用@EnableScheduling显示开启
  • 结合@ConditionalOnProperty设置是否开启或禁用调度任务
  • @Scheduled注解的方法,表示开启定时任务
  • fixedRatefixedDelay设置执行间隔
  • initialDelay设置第一次方法执行的延迟时间

上述的代码示例都已上传到Gitee
参考文章:

  • 英文文章
  • spring官网文章
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Springboot使用定时任务scheduler详解 的相关文章

随机推荐

  • mybatis动态数据源,分页插件失效

    mybatis动态数据源 xff0c 分页插件失效 发表于 xff1a 2020 08 18 20 42 47 阅读量 xff1a 9 作者 xff1a 黄叶 原因 xff1a 使用动态数据源 xff1a 数据正常但是total为0 解决
  • mybatis动态数据源配置使用事务不生效

    原因 xff1a 因为我使用的是配置的方式来加载数据源 xff0c 因此我们还需要对事务管理器进行一个配置 解决 xff1a 在代码中添加 配置事物 64 param dataSource 64 return 64 Bean public
  • Caffeine cache实现本地缓存(简单又清楚)

    Caffeine cache实现本地缓存题 缓存填充策略 手动加载 介绍 xff1a 使用方式 xff1a 同步加载 介绍 xff1a 使用方式 xff1a 异步加载 介绍 xff1a 注意 xff1a 异步和同步使用方式相似 这里的话主要
  • 商城后台系统 — 新手练习 —毕业设计

    商城后台系统 新手练习 毕业设计 业务功能介绍项目地址 xff1a 一 商品管理1 商品列表 描述 效果 2 添加商品 描述 效果 3 商品分类 描述 效果 4 商品类型 描述 效果 二 订单管理1 订单列表 描述 效果 2 订单设置 描述
  • CASE WHEN函数@sql学习

    mysql中可以使用CASE WHEN函数完成数据分组 CASE WHEN函数用来对数据进行判断和分组 来自MySQL触发器里的流程控制语句 知识 CASE WHEN是SQL编程中常用的条件控制语句 CASE WHEN的功能 xff1a 新
  • @Autowired注入为null — 4种常见情况

    64 Autowired注入为null 情况一 使用过滤器 原因解决 情况二 没有添加注解 原因解决 情况三 xff08 没有被扫描到 xff09 原因解决 情况四 xff08 手动new xff09 原因解决 情况一 使用过滤器 原因 因
  • TDD项目实战-命令行参数解析

    认识1 基本规则2 三步骤3 任务分解法总结 项目1命令行参数解析01 任务分解法与整体工作流程1 API 构思与组件划分2 功能分解与任务列表3 红绿灯循环 02 识别坏味道与代码重构1 引入多态接口2 使用 抽象工厂 模式的变体来替换分
  • mapper扫描问题(Invalid bound statement (not found))

    分析 xff1a 通常来说这种情况是mybatis没有配置好 但是还有一种可能是你的mapperscan扫描问题 解决 xff1a 使用这个的时候应该扫描的是mapper层 如果我们用成全局的扫描 xff08 根目录 xff09 xff0c
  • 找不到org.springframework.cloud.client.loadbalancer.reactive.OnNoRibbonDefaultCondition

    原因 xff1a 该类存在于spring cloud commons jar 引用的jar包存在冲突 新版本的spring cloud commons中取消了OnNoRibbonDefaultCondition类 解决 xff1a 引入依赖
  • Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springfra..问题

    原因 xff1a 依赖冲突 解决 xff1a 例如我的是spring cloud starter gateway和spring boot starter web和spring boot starter webflux依赖冲突排除 sprin
  • 重构 - 消除重复的new创建

    如下 xff1a 有时会遇到这种重复的new创建 span class token keyword public span span class token keyword class span span class token class
  • IDEA快捷键-重构

    文章目录 重构项目案例参考重构技巧1 消除重复new创建重构技巧2 提炼函数 xff0c 消除重复计算 提炼函数提炼变量搬移函数inlIne使用 xff08 内联 xff09 inLine重构局部变量inLine重构方法 重构重构菜单栏ID
  • 重构 - 提炼函数,消除重复代码

    一 参考资料二 重构步骤 以提炼重复计算函数为例子演示代码具体步骤1 提取重复new创建2 提取会变化的信息3 使用抽取的共有信息 xff0c 并删除原有信息4 提取计算函数5 使用卫语句 xff0c 简化代码逻辑 一 参考资料 重构 2
  • 模板方法 + 工厂变体消除重复if else

    模板方法 43 工厂消除重复if else 1 将重复代码 xff0c 抽取到抽象类中2 子类实现抽象类3 使用工厂获取对象 思维导图 xff1a 示例代码 xff1a 1 将重复代码 xff0c 抽取到抽象类中 span class to
  • mapstruct学习及使用详解

    映射器定义基本映射自定义映射方法从多个源对象映射映射嵌套对象更新现有实例继承配置逆映射映射期间的异常处理 数据类型转换隐式类型转换映射集合映射策略映射流映射枚举定义默认值或常量定义默认表达式 映射器检索策略映射定制装饰器 64 Before
  • 开窗函数@sql学习

    参考链接 https zhuanlan zhihu com p 98655285 mysql8 0 43 开窗函数 开窗函数又称OLAP函数 xff08 Online Analytical Processing xff09 1 开窗函数的语
  • LWIP学习系列(一):OSI模型以及TCP/IP模型的整理

    一 OSI模型与TCP IP模型的对比图 这张图是从网上搜来的 xff0c 我认为能够比较好的对应其中的两种模型的差别 学习lwip对其中部分协议有个大致的了解就行了 xff0c 具体需要的时候 xff0c 在按需求进行学习
  • win10 ubuntu16 双系统共用蓝牙鼠标

    最近给新笔记本电脑装了win10 43 ubuntu16双系统 xff0c 发现原来在win10下已经配对的蓝牙鼠标 xff0c 在ubuntu下配对后 xff0c win10就不能用了 xff0c 需要重新配对才行 xff0c 反之亦然
  • Validation校检使用及验证反模式问题,详细

    Validation校检认识基本使用验证 Spring MVC 控制器的输入验证 service层输入验证持久化层 实体输入使用验证组为不同的用例验证不同的对象自定义验证错误自定义验证器以编程方式验证 验证反模式 使用问题 xff09 仅在
  • Springboot使用定时任务scheduler详解

    目录 认识示例代码定时任务 调度任务开启调度添加定时任务以固定延迟执行定时任务 fixedDelay以固定速率执行定时任务 fixedRate延迟第一次初始化 initialDelay以 ISO 时间格式指定间隔 fixedRateStri