@Scheduled定时器

news/2024/12/13 17:03:34/

@Scheduled定时器

  • 一、基本使用
  • 二、参数说明
    • fixedDelay
    • fixedRate
    • initialDelay
    • cron
  • 三、cron 表达式
    • 参数说明
    • 实用性的案例
  • 四、@Scheduled注意事项
  • 五、配置文件
    • 1、fixedDelay
    • 2、fixedRate
    • 3、cron

一、基本使用

@Scheduled  // 由Spring定义,用于将方法设置为调度任务。如:定时执行一次或定时轮询执行一段代码。该注解放到需要定时执行的方式上@EnableScheduling  // 再项目启动类上添加注解@EnableScheduling,表示开启定时任务
@Scheduled(fixedDelay=20*1000)   //每隔20秒执行
public void scheduledTaskByFixedDelay() {log.info("定时任务开始 ByFixedDelay:" + DateUtils.getDatetimeString());String str = "Hello,,,World,,,每20秒,,,指定参数FixedDelay,,,";List<Map<String,String>> list = helloService.getTemp();log.info(str+ JSON.toJSONString(list));log.info("定时任务结束 ByFixedDelay:" + DateUtils.getDatetimeString());
}
@SpringBootApplication
@EnableScheduling
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

二、参数说明

fixedDelay

上一次任务执行完毕时间点之后多长时间再执行,任务的执行要等上一个任务执行结束。
它的间隔时间是根据上次的任务结束的时候开始计时的。
比如一个方法上设置了 fixedDelay=10*1000,那么当该方法某一次执行结束后,开始计算时间,当时间达到10秒,就开始再次执行该方法。

@Scheduled(fixedDelay=10000)   //每隔10秒执行@Scheduled(fixedDelay=60*60*1000)   //每隔1小时执行

fixedRate

上一次任务开始执行点之后指定时间后再执行(如果执行时间超过了间隔时间,那上一次任务执行完之后,立即执行下一个任务)
fixedRate 理解起来比较麻烦,它的间隔时间是根据上次任务开始的时候计时的。比如当方法上设置了 fiexdRate=5000,该执行该方法所花的时间是2秒,那么3秒后就会再次执行该方法。
但是这里有个坑,当任务执行时长超过设置的间隔时长,那会是什么结果呢。打个比方,比如一个任务本来只需要花2秒就能执行完成,我所设置的fixedRate=5000,但是因为网络问题导致这个任务花了7秒才执行完成。当任务开始时Spring就会给这个任务计时,5秒钟时候Spring就会再次调用这个任务,可是发现原来的任务还在执行,这个时候第二个任务就阻塞了(这里只考虑单线程的情况下,多线程后面再讲),甚至如果第一个任务花费的时间过长,还可能会使第三第四个任务被阻塞。被阻塞的任务就像排队的人一样,一旦前一个任务没了,它就立马执行。

@Scheduled(fixedRate=60000)   //任务开始执行后隔60秒执行@Scheduled(fixedRate=60*60*1000)   //任务开始执行后隔1小时执行

initialDelay

第一次任务将会延迟指定时间后启动

@Scheduled(fixedDelay=60*60*1000,initialDelay=60*1000)   //第一次任务延迟1分钟启动,之后每隔1小时执行

cron

该参数接受一个cron表达式,cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义。

@Scheduled(cron="秒 分 时 日 月 周 年")   // 年不是必需的,可省略

三、cron 表达式

@Scheduled(cron="秒 分 时 日 月 周 年")   // 年不是必需的,可省略

参数说明

其中,每个时间字段都有对应的取值范围和特殊符号。下面是每个时间字段的详细说明:

1、秒 (Seconds):取值范围为 0~59。例如,'0/5'表示每隔5秒触发一次。'*'表示每秒种都触发。允许使用特殊字符 , - * /2、分钟 (Minutes):取值范围为 0~59。例如,'0/5'表示每隔5分钟触发一次。'*'表示每分种都触发。允许使用特殊字符 , - * /3、小时 (Hours):取值范围为 0~23。例如,'0/2'表示每隔2小时触发一次。'*'表示每小时都触发。允许使用特殊字符 , - * /4、日期 (Day of Month):取值范围为 1~31。例如,'1,15'表示每月的1日和15日触发,'*'表示每天都触发。允许使用特殊字符 , - * ? / L W C5、月份(Month):取值范围为 1~12,也可以使用英文缩写JANFEBMAR等。例如,'1,6'表示一月和六月触发,'*'表示每个月都触发。允许使用特殊字符 , - * /6、星期 (Day of Week) :取值范围为 1~71 表示星期日,2 表示星期一,以此类推,也可以使用英文缩写 SUNMONTUE 等。例如,'2-6'表示星期一到星期五触发,'*' 表示每个星期都触发。允许使用特殊字符 , - * ? / L C #7、年份 (Year):可选字段,表示触发条件的年份。例如,'2023' 表示在2023年触发,'*' 表示每年都触发。允许使用特殊字符 , - * /// 在使用时,由于"月份中的日期"和"星期中的日期"这两个元素互斥的,必须要对其中一个设置?

除了取值范围,Cron 表达式还支持一些特殊符号,用于指定特定的触发条件,例如:

星号(*):代表所有可能的取值,表示不限制该时间字段的取值范围。
问号(?):仅在日期和星期字段中使用,表示不指定具体的取值,可以任意匹配。
斜线(/):表示间隔触发,例如在分钟字段中,"*/5"表示每隔5分钟触发一次。"0/15"表示从第0分钟开始,每15分钟。"3/20"表示从第3分钟开始,每20分钟(它和"3,23,43")的含义一样
逗号(,):用于指定多个取值,例如在小时字段中,"1,3,5" 表示在第 135 小时触发。
减号(-):用于指定一个范围,例如在月份字段中,"3-6" 表示三月到六月触发。"L" 字符仅被用于天(月)和天(星期)两个子表达式,它是单词"last"的缩写
如果在"L"前有具体的内容,它就具有其他的含义了。例如:"6L"表示这个月的倒数第6天
注意:在使用"L"参数时,不要指定列表或范围,因为这会导致问题
"W" 字符代表着工作日(Mon-Fri),并且仅能用于日历中。它用来指定离指定日的最近的一个星期日。大部分的商业处理都是基于工作周的,所以 W 字符可能是非常重要的。
例如,日域中的 15W 意味着 "离该月15号的最近一个工作日"。 假如15号是星期六,那么 trigger 会在14(星期五)触发,因为星期伍比星期一离15号更近。
"C" 字符代表"Calendar"的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。

实用性的案例

"0 0 10,14,16 * * ?"  每天上午10,14,16"0 0/30 9-17 * * ?"   朝九晚五工作时间内每半小时
"0 0 12 ? * WED" 表示每个星期三中午12"0 0 12 * * ?"   每天中午12点触发 
每天上午10:15触发: "0 15 10 ? * *"   "0 15 10 * * ?"   "0 15 10 * * ? *"
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发 
"0 * 14 * * ?"       在每天下午2点到下午2:59期间的每1分钟触发 
"0 0/5 14 * * ?"     在每天下午2点到下午2:55期间的每5分钟触发 
"0 0/5 14,18 * * ?"  在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
"0 0-5 14 * * ?"     在每天下午2点到下午2:05期间的每1分钟触发 
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:102:44触发 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
"0 15 10 15 * ?" 每月15日上午10:15触发 
"0 15 10 L * ?"  每月最后一日的上午10:15触发 
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发 @Scheduled(cron = "*/5 * * * * ?")  \\每隔5秒钟执行一次@Scheduled(cron = "0 */1 * * * ?")  \\每隔一分钟执行一次@Scheduled(cron = "0 26,29,33 * * * ?")  \\在各个小时的26分、29分、33分执行一次@Scheduled(cron = "0 0 */2 * * ?")  \\每隔两小时执行一次@Scheduled(cron = "0 0 1 * * ?")  \\每天凌晨1点执行一次@Scheduled(cron = "0 0 6,15,20 * * ?")  \\每天的6点、15点、20点触发定时任务@Scheduled(cron = "0 0 2 1 * ?")  \\每月1号凌晨2点执行一次@Scheduled(cron = "0 0 23 L * ?")  \\每月最后一天23点执行一次@Scheduled(cron = "0 0 3 ? * L")  \\每周星期六凌晨3点执行一次@Scheduled(cron = "0 0 12 ? * SUN")  \\每周星期天中午12点执行一次@Scheduled(cron = "0 0 0 L * ?")  \\每个月的最后一天执行一次@Scheduled(cron = "0 0/5 9-17 * * MON-FRI")  \\工作日的早上 9 点到下午 5 点,每隔 5 分钟触发定时任务

Scheduled(cron=“0 */1 * * * ?”)
每一分钟执行一次。比如第一次执行时间为2023-10-20 23:08:12,下一次2023-10-20 23:09:12,再下一次2023-10-20 23:10:12

@Scheduled(cron = “10 * * * * ?”)
每分钟的第十秒执行一次。比如第一次执行时间为2023-10-20 23:09:10,下一次2023-10-20 23:10:10,再下一次2023-10-20 23:11:10。 之所以用(23:09:10)举例,是因为上一个任务是在(23:08:12)才启动,所以任务只能从23:09:10开始

@Scheduled(cron = “*/10 * * * * ?”)
每十秒钟执行一次。比如第一次执行时间为2023-10-20 23:08:12,下一次2023-10-20 23:08:22,再下一次2023-10-20 23:08:32

四、@Scheduled注意事项

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

五、配置文件

1、fixedDelay

@Scheduled(initialDelay = 5, fixedDelayString = "${erwin.fixed-delay:2}", timeUnit = TimeUnit.SECONDS)
public void scheduledTaskByFixedDelay() {log.info("定时任务开始 ByFixedDelay:" + DateUtils.getDatetimeString());log.info("Hello,,,World,,,指定参数fixedDelay,,,");
}

配置文件 .yml

erwin:fixed-delay: 5

如果在配置文件中没有配置,则每隔2秒执行一次,如果配置了,就每隔5秒执行一次。initialDelay 表示,项目启动后,5秒开始执行第一次任务。
注意:${erwin.fixed-delay:2},冒号前后不能有空格。

2、fixedRate

@Scheduled(initialDelay = 5, fixedRateString = "${erwin.fixed-rate:2}", timeUnit = TimeUnit.SECONDS)
public void scheduledTaskByFixedRate() {log.info("定时任务开始 ByFixedRate:" + DateUtils.getDatetimeString());log.info("Hello,,,World,,,指定参数fixedRate,,,");
}

配置文件 .yml

erwin:fixed-rate: 5

3、cron

如果配置文件没有配,就会使用默认的值。

@Scheduled(cron = "${erwin.cron:0/10 * * * * ?}")
public void scheduledTaskByCron() {log.info("定时任务开始 ByCron:" + DateUtils.getDatetimeString());log.info("Hello,,,World,,,指定参数cron,,,");
}

配置文件 .yml

erwin:cron: 0/30 * * * * ?

http://www.ppmy.cn/news/1168325.html

相关文章

惊艳的Selenium技巧:探索基础和动作链的奇妙世界

1.Selenium简介 selenium可以帮助我们便捷的获取网站中动态加载的数据&#xff0c;也可以便捷实现模拟登录&#xff1b; selenium是基于浏览器自动化的一个模块&#xff0c;使用可以操作浏览器来帮我们实现一些自动化的操作&#xff01; Selenium 是一个广泛使用的自动化测试工…

《数据结构、算法与应用C++语言描述》-队列的应用-图元识别问题

《数据结构、算法与应用C语言描述》-队列的应用-图元识别问题 图元识别 问题描述 数字化图像是一个 mxm 的像素矩阵。在单色图像中&#xff0c;每一个像素要么为0&#xff0c;要么为 1。值为0的像素表示图像的背景。值为1的像素表示图元上的一个点&#xff0c;称其为图元像素…

Android---RecyclerView替代ListView

RecyclerView 简称RV&#xff0c;是作为 ListView 和 GridView 的加强版出现&#xff0c;目的是在有限的屏幕之上展示大量的内容。因此&#xff0c;RecyclerView 的复用机制的实现是它的一个核心部分。 RV 常规使用方式 // 1 RecyclerView.setLayoutManager(); // 2 Recycler…

S7-1200通过CM CANopen模块与KINCO伺服连接

CM CANopen模块简介 CM CANopen模块&#xff08;Profinet转CANopen&#xff09;来自瑞典HMS &#xff0c;由西 门子授权HMS公司开发&#xff0c;与S7-1200完美兼容。 可做为S7-1200与CANopen/CAN设备之间的桥梁&#xff0c;能够联接任意 CANopen或CAN 2.0A设备到SIMATIC S7-1…

打造自己的前端组件库(奶妈版,超详细)

打造自己的前端组件库 demo是开源的&#xff0c;自己上npm 或者 github 上都能搜到 新建vue项目(sass js vue2) vue create yt-ui 修改文件目录(如下) 修改&#xff1a; 1.src 更名 examples; 2. src/components移动到项目最外层&#xff1b;3.vue.config.js更改入口文件 /…

树状数组学习笔记

树状数组 树状数组的用途&#xff0c;主要是可以以 O ( log ⁡ n ) O(\log n) O(logn) 的时间复杂度维护前缀和。 对于树状数组的使用&#xff0c;我们开一个数组 c&#xff0c;c[x] 表示 [ x − lowbit ( x ) 1 , x ] [x-\text{lowbit}(x)1,x] [x−lowbit(x)1,x] 的区间和…

3、Kafka Broker

4.1 Kafka Broker 工作流程 4.1.1 Zookeeper 存储的 Kafka 信息 &#xff08;1&#xff09;启动 Zookeeper 客户端。 [hadoop102 zookeeper-3.5.7]$ bin/zkCli.sh&#xff08;2&#xff09;通过 ls 命令可以查看 kafka 相关信息。 [zk: localhost:2181(CONNECTED) 2] ls /kaf…

JVM第十七讲:调试排错 - Java 问题排查之Linux命令

调试排错 - Java 问题排查之Linux命令 本文是JVM第十七讲&#xff0c; Java 问题调试排错。Java 在线问题排查主要分两篇&#xff1a;本文是第一篇&#xff0c;通过linux常用命令排查。 文章目录 调试排错 - Java 问题排查之Linux命令在项目中&#xff0c;日志操作的常用命令1、…