java中定时任务 schedule 分布式下没有锁住 时间不同步 执行滞后 相对时间 系统时间 spring springboot

java.util.Timer计时器可以进行:管理任务延迟执行("如1000ms后执行任务"),及周期性执行("如每500ms执行一次该任务")。

但是,Timer存在一些缺陷,应考虑使用ScheduledThreadPoolExecutor代替,Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。

Timer的另一个问题在于,如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。

https://www.cnblogs.com/felixzh/p/11899051.html

今天本地测试定时任务的时候, 修改完本地系统时间,发现到时间后定时任务并没有执行, 经过一番分析调试才发现一个get到一个技能: 如果项目启动后, 修改系统时间则定时任务不会生效, 但是项目若是在修改系统时间后启动 则定时任务到点会执行, 原因是缓存了时间;

但是经过一些搜集发现,修改系统时间的定时任务问题也分情况: Timer类的调度是基于绝对的时间的,而不是相对的时间,因此Timer类对系统时钟的变化是敏感的,举个例子,假如你希望任务1间隔10秒执行一次,某个时刻,你将系统时间提前了6秒,那么任务1就会在4秒后执行,而不是10秒后。在 ScheduledThreadPoolExecutor中任务的调度是基于相对时间的,原因是它在任务的内部 存储了该任务距离下次调度还需要的时间(使用的是基于 System#nanoTime实现的相对时间 ,不会因为系统时间改变而改变,如距离下次执行还有10秒,不会因为将系统时间调前6秒而变成4秒后执行, 相当于是缓存了系统时间)。

Spring定时任务之修改系统时间问题_zhanglq1202的博客-CSDN博客

配置线程池。因为默认是单线程。会因为Thead.sleep()阻塞。

java 复制代码
spring:
  task:
    scheduling:
      pool:
        size: 10

@EnableAsync+@Async是让当前方法异步。例如当前方法是每秒执行一次,但因为阻塞了,就不会再每秒执行。 给方法加上@Async,就可以继续每秒执行。

@Schedule 解决定时任务推迟执行_@sechedule 每5秒_Dily_Su的博客-CSDN博客

相关推荐
Grey Zeng2 小时前
Java SE 25新增特性
java·jdk·jdk新特性·jdk25
雨白3 小时前
Java 线程通信基础:interrupt、wait 和 notifyAll 详解
android·java
AAA修煤气灶刘哥4 小时前
别让Redis「歪脖子」!一次搞定数据倾斜与请求倾斜的捉妖记
redis·分布式·后端
架构师沉默7 小时前
设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
java·后端·架构
Java中文社群9 小时前
重要:Java25正式发布(长期支持版)!
java·后端·面试
每天进步一点_JL10 小时前
JVM 类加载:双亲委派机制
java·后端
用户2986985301410 小时前
Java HTML 转 Word 完整指南
java·后端
渣哥10 小时前
原来公平锁和非公平锁差别这么大
java
渣哥11 小时前
99% 的人没搞懂:Semaphore 到底是干啥的?
java
J2K11 小时前
JDK都25了,你还没用过ZGC?那真得补补课了
java·jvm·后端