Spring内置定时任务调度@Scheduled使用详解

 更新时间:2020年12月04日 10:17:37   作者:codedot  
这篇文章主要介绍了Spring内置定时任务调度@Scheduled使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

Spring提供了@Scheduled注解用于定时任务。

一、@Scheduled的基本使用

启用调度支持:@EnableScheduling

可以将@Scheduled注释与触发器元数据一起添加到方法中。例如,以下方法每隔5秒调用一次,并具有固定的延迟,这意味着周期是从前面每次调用的完成时间开始计算的

@Scheduled(fixedDelay=5000)
public void doSomething() {
// something that should execute periodically
}

如果需要固定速率执行,可以更改批注中指定的属性名。以下方法每5秒调用一次(在每次调用的连续开始时间之间计算)

@Scheduled(fixedRate=5000)
public void doSomething() {
// something that should execute periodically
}

对于固定延迟和固定速率任务,可以通过指示在首次执行方法之前要等待的毫秒数来指定初始延迟

@Scheduled(initialDelay=1000, fixedRate=5000)
public void doSomething() {
// something that should execute periodically
}

如果简单的周期性调度不够表达,可以提供cron表达式。例如,以下命令仅在工作日执行:

@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
// something that should execute on weekdays only
}

实现SchedulingConfigurer接口,重写configureTasks方法:

@Schedule注解的一个缺点就是其定时时间不能动态更改,它适用于具有固定任务周期的任务,若要修改任务执行周期,只能走“停服务→修改任务执行周期→重启服务”这条路。而基于 SchedulingConfigurer 接口方式可以做到。SchedulingConfigurer 接口可以实现在@Configuration等注解类上。

ScheduledTaskRegistrar类包括以下几个重要方法:

void addTriggerTask(Runnable task, Trigger trigger)
void addTriggerTask(TriggerTask task)
void addCronTask(Runnable task, String expression)
void addCronTask(CronTask task)
void addFixedRateTask(Runnable task, long interval)
void addFixedRateTask(IntervalTask task)
void addFixedDelayTask(Runnable task, long delay)
void addFixedDelayTask(IntervalTask task)

具体实现参考如下:

@Component
public class TestTask implements SchedulingConfigurer {
 
  @Override
  public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    taskRegistrar.addTriggerTask(new Runnable() {
      @Override
      public void run() {
        // 定时任务要执行的内容
        System.out.println("【开始执行定时任务。。。】");
      }
    }, new Trigger() {
      @Override
      public Date nextExecutionTime(TriggerContext triggerContext) {
        // 定时任务触发,可修改定时任务的执行周期
        String cron = "0 0/5 * * * ?"; //可以将表达式配置在数据库中
        CronTrigger trigger = new CronTrigger(cron);
        Date nextExecDate = trigger.nextExecutionTime(triggerContext);
        return nextExecDate;
      }
    });
  }
}

提示:如果在数据库修改时格式出现错误,则定时任务会停止,即使重新修改正确;此时只能重新启动项目才能恢复。

二、使用@Scheduled注意事项

  • spring的注解@Scheduled 需要写在实现方法上;
  • 定时器的任务方法不能有返回值(如果有返回值,spring初始化的时候会告诉你有个错误、需要设定一个proxytargetclass的某个值为true),不能指向任何的参数;
  • 如果该方法需要与应用程序上下文的其他对象进行交互,通常是通过依赖注入来实现;
  • 实现类上要有组件的注解@Component。

三、使用@Scheduled常见问题

单线程任务丢失,转为异步线程池

默认的 ConcurrentTaskScheduler 计划执行器采用Executors.newSingleThreadScheduledExecutor() 实现单线程的执行器。因此,对同一个调度任务的执行总是同一个线程。如果任务的执行时间超过该任务的下一次执行时间,则会出现任务丢失,跳过该段时间的任务。上述问题有以下解决办法:

采用异步的方式执行调度任务,配置 Spring 的 @EnableAsync,在执行定时任务的方法上标注 @Async配置任务执行池,线程池大小 n 的数量为 单个任务执行所需时间 / 任务执行的间隔时间。如下:

//每30秒执行一次
@Async("taskExecutor")
@Scheduled(fixedRate = 1000 * 3)
public void reportCurrentTime(){
  System.out.println ("线程" + Thread.currentThread().getName() + "开始执行定时任务===&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&7&&&====》"
      + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  long start = System.currentTimeMillis();
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot异常处理之异常显示的页面问题

    SpringBoot异常处理之异常显示的页面问题

    这篇文章主要介绍了SpringBoot异常处理异常显示的页面的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • SpringBoot 整合 EasyExcel 实现自由导入导出功能

    SpringBoot 整合 EasyExcel 实现自由导入导出功能

    在实际的业务系统开发过程中,操作 Excel 实现数据的导入导出基本上是个非常常见的需求,这篇文章主要介绍了SpringBoot 整合 EasyExcel 实现自由导入导出功能,需要的朋友可以参考下
    2024-06-06
  • 一篇文章带你入门Java修饰符

    一篇文章带你入门Java修饰符

    Java语言提供了很多修饰符,主要分为以下两类:访问修饰符;非访问修饰符。修饰符用来定义类、方法或者变量,通常放在语句的最前端。我们通过下面的例子来说明,下面就跟小编一起来看下吧
    2021-08-08
  • Java数据脱敏实现的方法总结

    Java数据脱敏实现的方法总结

    数据脱敏,指的是对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护,本文主要是对后端数据脱敏实现的简单总结,希望对大家有所帮助
    2023-07-07
  • 详解java 对象锁与类锁

    详解java 对象锁与类锁

    这篇文章主要介绍了java 对象锁与类锁的相关资料,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-09-09
  • Springboot容器级后置处理器BeanDefinitionRegistryPostProcessor

    Springboot容器级后置处理器BeanDefinitionRegistryPostProcessor

    这篇文章主要介绍了Springboot容器级后置处理器BeanDefinitionRegistryPostProcessor,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • Mybatis-Plus select不列出全部字段的方法

    Mybatis-Plus select不列出全部字段的方法

    这篇文章主要介绍了Mybatis-Plus select不列出全部字段的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Collections.shuffle()方法实例解析

    Collections.shuffle()方法实例解析

    这篇文章主要介绍了Collections.shuffle()方法实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • SpringCloud2020.0.x版UnderTow AccessLog相关配置简介

    SpringCloud2020.0.x版UnderTow AccessLog相关配置简介

    本文详细介绍了SpringCloud中AccessLog的相关配置,我们可以根据文中的相关数据配置出所需的AccessLog的信息以及格式,感兴趣的小伙伴可以参考一下
    2021-08-08
  • Maven包冲突导致NoSuchMethodError错误的解决办法

    Maven包冲突导致NoSuchMethodError错误的解决办法

    web 项目 能正常编译,运行时也正常启动,但执行到需要调用 org.codehaus.jackson 包中的某个方法时,产生运行异常,这篇文章主要介绍了Maven包冲突导致NoSuchMethodError错误的解决办法,需要的朋友可以参考下
    2024-05-05

最新评论