使用springboot时,解决@Scheduled定时器遇到的问题

 更新时间:2021年11月02日 08:36:08   作者:teng_sd_cn  
这篇文章主要介绍了使用springboot时,解决@Scheduled定时器遇到的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

@Scheduled定时器遇到的问题

@Scheduled 这个注解确实给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用定时任务了。

但是,我们需要注意的是,@Scheduled 并不一定一定会按时执行。

因为使用@Scheduled 的定时任务虽然是异步执行的,但是,不同的定时任务之间并不是并行的!!!!!!!!

在其中一个定时任务没有执行完之前,其他的定时任务即使是到了执行时间,也是不会执行的,它们会进行排队。

也就是如果你想你不同的定时任务互不影响,到时间就会执行,那么你最好将你的定时任务方法自己搞成异步方法,这样,

定时任务其实就相当于调用了一个线程执行任务,一瞬间就结束了。当然,也可以勉强当做是任务都会定时执行。

下面说一下@Scheduled 注解的几个参数

一、可以通过配置文件配置进来的

使用表达式,该表达式表示每一秒中执行一次。如果上一次方法超过了定时时间还没有执行完,那么下一次定时不会执行,

直到上次方法执行完后,就会立即执行下一次的定时任务

该方式在工程启动的时候,并不会立即执行,会按照定时表达式的规律进行执行。例如这里,就是1秒后才会执行。

@Scheduled(cron="0/1 * * * * ?")   

使用固定速率。该表达式表示每隔一秒钟执行一次。如果上一次方法超过了1秒钟还没执行完,下一次任务也不会执行,直到

上次方法执行完,下次的定时就会立即执行。

该方式在工程启动的时候,会立即执行,接下来会按规律进行执行。

@Scheduled(fixedRateString="1000")   // 单位:毫秒

该方式和上一个的不同在于多加了一个参数,这个参数是一个初始化参数。

加上initialDelayString后,在刚启动的时候,就不会立即执行了,而是会等到10秒之后才会执行,即使fixedRateString才

1秒钟。也会在10秒后才会第一次执行。

注意:initialDelayString不能喝cron组合使用。

@Scheduled(fixedRateString="1000",initialDelayString="10000")

使用固定延迟。该表达式表示每次执行完后一秒再次执行。每一次执行,无论执行多长时间,下一次执行都会在上一次方法

执行完后,再过一秒钟,再次执行。

该方式在工程启动的时候,会立即执行,接下来会按规律进行执行。

@Scheduled(fixedDelayString="1000")

二、不可通过配置文件配置的 (作用相同)

   @Scheduled(fixedRate=1000)      // 它们都是接受一个long类型的参数
   @Scheduled(fixedDelay=1000)
   @Scheduled(fixedRate=1000,initialDelay=10000)

这里粘贴一下cron表达式的规则:

字段 允许值 允许的特殊字符
0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
年(可选) 留空, 1970-2099 , - * /

定时任务@Scheduled使用的那些坑

@Scheduled是spring自带的注解,默认是单线程,常用作定时任务使用,但是如果是集群版的机器的话,就考虑加上分布式锁或者使用分布式定时任务代替。

一、使用的那些坑?

1.单线程

因为@Scheduled默认使用的是单线程,如果有两个任务A和B,那么任务A要是阻塞了,任务B就无法执行。

2.@Async和@EnableAsync

为了解决单线程带来的线程阻塞问题,我们可以使用@Async和@EnableAsync两个注解采用异步的方式去处理,这样就是不同的线程去执行,但是这种方式也带来一个新的问题,那就是如果任务A的任务执行时间>任务调度周期时间的话,就会发生上一个任务未执行完毕,下一个任务又开始执行的逻辑,这种也是有风险的。所以最好使用多线程方式,自己控制线程池的数量,线程名称等。

二、使用多线程

需要实现SchedulingConfigurer接口,然后自定义线程池,这样凡是用到@Scheduled注解的都可以用该线程池,同时也解决了上述比较坑的两个问题。

@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }
    @Bean
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(20, (Runnable r) -> {
            Thread thread = new Thread(r);
            thread.setName("自定义线程名称");
            return thread;
        });
    }
}

以上这一行

thread.setName(“自定义线程名称”);

是设置线程名称,可以通过Thread.currentThread().getName()拿到该名称,便于在日志中进行排查问题。

小结一下

集群版本如果要使用@Scheduled的话,需要加分布式锁来控制,或者直接用分布式定时任务Elasticjob或者xxl-job等。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java Swing程序设计实战

    Java Swing程序设计实战

    今天教大家怎么用JavaSwing工具包实现一个程序的界面设计,文中有非常详细的代码示例及注释,对正在学习Java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • Spring你不知道的一种解耦模式

    Spring你不知道的一种解耦模式

    本文介绍一种方法,服务定位模式Service Locator Pattern来解决,它帮助我们消除紧耦合实现及其依赖性,并提出将服务与其具体类解耦
    2023-01-01
  • 详解JAVA的控制语句

    详解JAVA的控制语句

    这篇文章主要介绍了Java中的控制语句,循环等语句是Java编程中流程控制的基础,需要的朋友可以参考下,希望能够给你带来帮助
    2021-11-11
  • 浅谈Java实现分布式事务的三种方案

    浅谈Java实现分布式事务的三种方案

    现在互联网下,分布式和微服务横行,难免会遇到分布式下的事务问题,当然微服务下可能没有分布式事务,但是很多场景是需要分布式事务的。下面就来介绍下什么是分布式事务和分布式事务的解决方案
    2021-06-06
  • Android仿微信实现左滑显示删除按钮功能

    Android仿微信实现左滑显示删除按钮功能

    这篇文章主要为大家详细介绍了java仿微信实现左滑显示删除按钮功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • Java遍历Properties所有元素的方法实例

    Java遍历Properties所有元素的方法实例

    这篇文章主要介绍了Java如何遍历Properties所有元素的方法,大家可以参考使用
    2013-11-11
  • java实现五子棋大战

    java实现五子棋大战

    这篇文章主要为大家详细介绍了java实现五子棋大战,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Mybatis plus关闭驼峰命名的四种方法(防止出现查询为Null)

    Mybatis plus关闭驼峰命名的四种方法(防止出现查询为Null)

    这篇文章主要介绍了Mybatis plus关闭驼峰命名的四种方法(防止出现查询为Null),数据库的字段命名方式为使用下划线连接,对应的实体类应该是驼峰命名方式,而我使用的是和数据库同样的命名方式,需要的朋友可以参考下
    2022-01-01
  • Java中的内存泄露问题和解决办法

    Java中的内存泄露问题和解决办法

    大家好,本篇文章主要讲的是Java中的内存泄露问题和解决办法,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • 实例化JFileChooser对象报空指针异常问题的解决办法

    实例化JFileChooser对象报空指针异常问题的解决办法

    今天小编就为大家分享一篇关于实例化JFileChooser对象报空指针异常问题的解决办法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02

最新评论