定时任务全解

在项目开发过程中,经常需要定时任务来帮助我们来做一些内容,springboot 默认已经帮我们实行了,开发者只需要添加相应的注解就可以实现。

一、Spring Task 定时任务1.1 静态定时任务(基于 @Scheduled 注解)1.1.1 pom 配置

pom 包里面只需要引入包即可:

1.1.2 启动类启用定时

在启动类上面加上即可开启定时:

注意:这里的注解,它的作用是发现注解的任务并由后台执行。没有它的话将无法执行定时任务。

引用官方文档原文:

ensures that a background task executor is created. Without it, nothing gets scheduled.

官方文档地址:

1.1.3 创建定时任务实现类

定时任务1:每过 6 秒执行

定时任务2:每过 6 秒执行

注意:上一次执行完毕时间点之后 6 秒再执行,不会等待上一个定时任务执行完毕再启动下一个定时任务,不论上次定时任务执行时间是多少。

定时任务3:每过上一个定时任务执行完毕之后的 6 秒执行

注意:上一次执行完毕时间点之后 6 秒再执行,等待上一次定时任务执行完毕之后再间隔 6 秒执行下一个定时任务。

1.1.4 参数说明

参数可以接受两种定时的设置每隔 6 秒执行定时任务:

一种是我们常用的,另一种是

fixedRate 说明

:上一次开始执行时间点之后再执行,参数类型为 long,单位 ms;

:与的含义一样,只是将参数类型变为 String;

:上一次执行完毕时间点之后再执行,参数类型为 long,单位 ms;

:与含义一样,只是参数类型变为 String;

:表示延迟多久再第一次执行任务,参数类型为 long,单位 ms;

:与的含义一样,只是将参数类型变为 String;

:时区,默认为当前时区,一般没有用到。

1.1.5 Cron 表达式

Cron 表达式有专门的语法,而且感觉有点绕人,不过简单来说,大家记住一些常用的用法即可,特殊的语法可以单独去查。

Cron 表达式是由一串字符串表示,使用的形式组合成完整表达式,Cron 表达式由空格将其划分为 6 或 7 个域,每一个域代表一个含义解释:

1.1.5.1 域解释

注意:第六位的取值:1-7 表示的是星期一至星期日

1.1.5.2 特殊符号解释

(*)星号

可以理解为每的意思,每秒,每分,每天,每月,每年;

(?)问号

只能用在每月第几天和星期两个域。表示不指定值,当 2 个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为;

(-)减号

表达一个范围,如在小时字段中使用 "10-12",则表示从10到12点,即 10, 11, 12;

(,)逗号

表达一个列表值,如在星期字段中使用 "1, 2, 4",则表示星期一,星期二,星期四,也可以使用单词缩写来指定,例如:"MON,WED,FRI" 在星期域里表示 "星期一、星期三、星期五;

(/)斜杠

表示起始时间开始触发,然后每隔固定时间触发一次,例如在分域使用 5/20 ,则意味着5分,25分,45分,分别触发一次,另外:,等同于;

(L)字符

表示最后,只能出现在星期和每月第几天域,如果在星期域使用 1L,意味着在最后的一个星期日触发;

(W)字符

表示有效工作日(周一到周五),只能出现在每月第几日域,系统将在离指定日期的最近的有效工作日触发事件。注意一点,W 的最近寻找不会跨过月份; LW : 这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

(#)字符

用于确定每个月第几个星期几,只能出现在每月第几天域,例如在1#3,表示某月的第三个星期日。

官方例子:

1.2 动态定时任务(基于 SchedulingConfigurer 接口)

为了演示效果,这里选用 Mysql 数据库保存 Cron 表达式,使用 Mybatis 框架来查询和调整定时任务的执行周期,然后观察定时任务的执行情况。当然,可以使用静态配置文件的形式配置。

1.2.1 pom 配置

1.2.2 添加数据库记录

在 mysql 数据库中创建数据库,并创建数据库表:

在项目中的添加数据源:

1.2.3 创建定时器

数据库准备好数据之后,编写要定时执行的任务类,实现接口,重写方法:

三、Timer 定时任务

这个目前在项目中很少用,直接给出示例代码。具体的介绍可以查看。的内部只有一个线程,如果多个任务的话就会顺序执行,这样任务的延迟时间循环时间就会出现问题。

观察测试结果,能够发现配置的任务,每隔被执行了一次,执行线程默认都是这个线程,并且启动的时机是 new 出 Timer 并执行方法的时候。

四、ScheduledExecutorService 定时任务

延时执行的线程池,对于多线程环境下的定时任务,推荐用 代替 定时器。

4.1 等待定时任务执行完毕再进行下一次定时任务

创建一个线程数量为的任务线程池,同一时刻并向它提交个定时任务,用于测试延时任务的并发处理。执行的方法,设置任务线程池的初始任务延迟时间为秒,并在上一次执行完毕时间点之后秒再执行下一次任务。

测试结果如下,我们可以发现每隔秒的时间间隔,就会有个定时任务同时执行。因为在任务线程池初始化时,我们同时向线程池提交了个任务,这四个任务会完全利用线程池中的个线程进行任务执行。

4.2 固定时间进行定时任务

创建一个线程数量为的任务线程池,同一时刻并向它提交个定时任务,用于测试延时任务的并发处理。每个任务分别执行的方法,设置任务线程池的初始任务延迟时间为秒,并在上一次开始执行时间点之后秒再执行下一次任务。

测试结果如下,我们可以发现每隔 秒的时间间隔,就会有 个定时任务同时执行,因为在任务线程池初始化时,我们同时向线程池提交了 个任务,这四个任务会完全利用线程池中的 个线程进行任务执行。

五、配置任务线程池(实现多线程并发处理)

上述配置都是基于单线程的任务调度,如何引入多线程提高延时任务并发处理能力?

提供了一个配置接口。我们通过 配置文件实现接口,并重写 方法,向注册一个任务线程对象即可。

参考博文:

SpringBoot 创建定时任务(配合数据库动态执行)

springboot(九):定时任务

spring boot项目中处理Schedule定时任务

SpringBoot定时任务及Cron表达式详解

实战Spring Boot 2.0系列(六) - 单机定时任务的几种实现

-END-

技术改变生活,

菜鸟程序员的成长之路。

欢迎关注:木鲸鱼

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181217G1H5CQ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券