【第十二篇】 SpringBoot定时任务
简介
本文介绍了Java中实现定时任务的两种方法:基于java.util.Timer类的简单实现和SpringTask框架。Timer通过创建TimerTask和Timer对象实现定时任务,但需注意其非守护线程特性。SpringTask作为Spring框架的轻量级调度模块,通过@Scheduled注解提供多种调度方式(cron表达式、固定延迟/频率执行),支持配置线程池参数,SpringTask在集群环境下具有一定的局限性。两种方案各有适用场景,开发者可根据项目需求选择。
目录
一、Java程序实现简单定时任务
1、Demo程序
2、参数解析
3、扩展
二、Spring Task定时任务框架
1、开启定时任务功能
2、使用定时任务
(1)cron表达式实现开启定时任务
(2)固定延迟执行
(3)固定频率执行
3、Spring Task相关配置
4、使用注意事项
(1)参数互斥
(2)方法要求
(3)线程池配置
(4)集群环境
一、Java程序实现简单定时任务
1、Demo程序
在Java的util类中提供的有定时任务的简单实现,例如下面的例子,只需要创建一个具体任务TimerTask的对象指定具体需要做的任务,然后再创建一个定时器Timer的对象去执行具体任务即可。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class DemoSchedule {public static void main(String[] args) {// 1、创建一个定时器Timer timer = new Timer();// 2、创建一个具体需要执行的任务TimerTask task = new TimerTask() {@Overridepublic void run() {String nowDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());System.out.println("定时任务正在执行..." + nowDate);}};// 当前线程开始后,立即启动定时器,并每三秒执行一次timer.schedule(task,0L,3000L);}
}
2、参数解析
Timer对象schedule方法总共有四个重载,入参大致相同,解析:
- TimerTask:具体需要执行的任务。
- delay:距当前线程启动后,多久启动定时器。
- time/firstTime:什么时候启动定时器。
- period:定时器执行具体任务时间间隔。
示例:
3、扩展
在当前线程启动之后,可以发现程序并没有停止。因为Timer创建的线程是非守护线程,即使你的main方法执行完毕,Timer线程仍然会保持 JVM 运行,直到你显式调用 timer.cancel()或程序被终止。
二、Spring Task定时任务框架
Spring Task是Spring框架提供的一个轻量级任务调度模块,它简化了定时任务的开发和管理。与Quartz相比,Spring Task更加轻量、配置简单,适合大多数基本的定时任务需求。
1、开启定时任务功能
Spring Task在SpringBoot的起步依赖中已被引入,所以无须引入任何依赖,只需要在启动类上添加@EnableScheduling注解,开启定时任务功能即可。
2、使用定时任务
创建一个类,并将该类交给IOC容器管理,这里是使用的@Component注解。然后在类里面创建需要定时执行的任务方法,并使用@Scheduled()注解在任务方法上进行声明。
@Scheduled()注解能够接收很多不同的参数,一种参数就代表了一种实现。有关数字的默认单位都是毫秒。
- cron:依据cron表达式的标准进行执行任务。
- zone:指定 Cron 表达式使用的时区。
- fixedDelay:固定延迟执行(上一次任务结束到下一次任务开始的间隔)。
- fixedDelayString:效果同fixedDelay,但支持字符串配置(如占位符)。
- fixedRate:固定频率执行(两次任务开始时间的间隔,不考虑任务执行时间)。
- fixedRateString:效果同fixedRate,但支持字符串配置(如占位符)。
- initialDelay:首次执行的延迟时间(仅对fixedDelay/fixedDelayString有效)。
- initialDelayString:效果同initialDelay,但支持字符串配置(如占位符)。
- timeUnit:指定时间单位(影响 fixedDelay/fixedRate/initialDelay)。
(1)cron表达式实现开启定时任务
在@Scheduled(cron = "*/3 * * * * *")注解中使用cron属性,然后进行赋值,那么当前项目启动之后就会以vron表达式的效果进行执行任务方法。
(2)固定延迟执行
在@Scheduled()注解中使用fixedDelay或者fixedDelayString属性,然后进行赋值,默认的时间单位都是毫秒,可以通过timeUnit属性进行指定。fixedDelay或者fixedDelayString属性表示的是本次任务距上次任务执行结束之后延迟多久执行。
fixedDelay属性实现。
fixedDelayString属性实现。该属性可以读取配置文件内容。
(3)固定频率执行
在@Scheduled()注解中使用fixedRate或者fixedRateString属性,然后进行赋值,默认的时间单位都是毫秒,可以通过timeUnit属性进行指定。fixedRate或者fixedRateString属性表示的是每隔多久执行一次任务方法,与任务方法的执行时长无关。
fixedRate属性实现。
fixedRateString属性实现。该属性可以读取配置文件内容。
3、Spring Task相关配置
可以在项目的配置文件中针对定时任务进行配置,下面是一个简单的示例。
spring:task:scheduling:# 任务调度池大小,默认1pool:size: 1# 任务调用线程名称前缀 默认为scheduling-thread-name-prefix: xbb_shutdown:# 线程池关闭时等待所有任务完成await-termination: false# 调度线程关闭前最大等待时间,确保最后一定关闭await-termination-period: 10s
4、使用注意事项
(1)参数互斥
cron、fixedDelay、fixedRate 三者必须且只能指定一个。
(2)方法要求
- 必须是无参方法
- 返回类型通常为void(非void返回值会被忽略)
(3)线程池配置
- 默认使用单线程执行所有定时任务
- 可通过 TaskScheduler 配置自定义线程池
(4)集群环境
- Spring Task 本身不支持分布式调度
- 集群环境下需使用 Quartz 等支持分布式的调度框架