目录
- 认识
- 示例代码
- 定时任务 / 调度任务
- 开启调度
- 添加定时任务
- 以固定延迟执行定时任务--fixedDelay
- 以固定速率执行定时任务--fixedRate
- 延迟第一次初始化--initialDelay
- 以 ISO 时间格式指定间隔--fixedRateString
- 使用 Cron 表达式定义间隔
- 结论
认识
能够让我们在指定的某个时间段自动执行任务,不需要自己去手动触发。
如:定时发送邮件、定时发送优惠卷等…
示例代码
文章中的代码,保存在Gitee中
定时任务 / 调度任务
开启调度
-
默认情况下不开启定时任务,如果想使用添加@EnableScheduling
来显示启动
@SpringBootApplication
@EnableScheduling
public class SpringSchedulerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSchedulerApplication.class, args);
}
}
-
更好的做法,是定义一个定时器的配置类,在结合@ConditionalOnProperty
控制定时任务的开启和关闭
@Configuration
@EnableScheduling
@ConditionalOnProperty(name = "scheduler.enabled", matchIfMissing = true)
public class SchedulerConfig {
}
添加定时任务
默认单位都为毫秒(ms)
以固定延迟执行定时任务–fixedDelay
-
fixedDelay
属性配置定时任务在指定延迟时间后执行
-
新任务要等待前一个任务完成,示例如下:
@Scheduled(fixedDelay = 2000)
public void computePrice() throws InterruptedException {
log.info("current time: {}", LocalTime.now());
Thread.sleep(4000);
}
以固定速率执行定时任务–fixedRate
-
fixedRate
属性配置定时任务以固定时间执行定时任务,示例如下:
@Scheduled(fixedRate = 3000)
public void refreshPricingParameters() throws InterruptedException {
log.info("current time: {}", LocalTime.now());
Thread.sleep(6000);
}
-
在这里,我们通过设置fixedRate
为3000毫秒,使refreshPricingParameters
方法每隔3秒就会执行一次。
-
但是由于Scheduled
默认是单线程,导致打印时间为6秒间隔(Thread.sleep(6000))
。
-
如果想不被前一个任务的影响,可以通过下面两种方法解决:
-
通过开启异步任务
@Configuration
@EnableScheduling
@EnableAsync
@ConditionalOnProperty(name = "scheduler.enabled", matchIfMissing = true)
public class SchedulerConfig {
}
@Scheduled(fixedRate = 3000)
@Async
public void refreshPricingParameters() throws InterruptedException {
log.info("current time: {}", LocalTime.now());
Thread.sleep(6000);
}
-
定时器默认不并行执行是因为线程池默认大小为1,可以通过配置**spring.task.scheduling.pool.size
**调整线程池大小。
延迟第一次初始化–initialDelay
-
使用fixedRate
和fixedDelay
属性,方法的第一次调用,会在上下文初始化完成后通过指定的时间进行调度。
-
但是可以通过initialDelay
属性,指定第一次方法执行的延迟时间。示例如下:
@Scheduled(initialDelay = 5000, fixedRate = 3000)
@Async
public void refreshPricingParametersTemp() {
log.info("current time: {}", LocalTime.now());
}
以 ISO 时间格式指定间隔–fixedRateString
-
可以通过这个文档ISO-文档了解ISO时间格式,示例如下:
@Scheduled(fixedDelayString = "PT02S")
public void computePrice_TEMP() throws InterruptedException {
log.info("current time: {}", LocalTime.now());
Thread.sleep(4000);
}
- 在这里,设置
fixedDelayString
值为PT02S
,表示调用之间以 2 秒的固定延迟执行。
-
除此之外,fixedDelayString
还支持读取配置文件进行设置,示例如下:
@Scheduled(fixedDelayString = "${interval}")
public void computePriceTemp() throws InterruptedException {
log.info("current time: {}", LocalTime.now());
Thread.sleep(4000);
}
interval: PT02S
interval=PT02S
使用 Cron 表达式定义间隔
-
cron
表达式,用于设置更加复杂的时间。示例如下:
@Scheduled(cron = "0/2 * * * * ?")
public String computePrice() throws InterruptedException {
log.info("current time: {}", LocalTime.now());
return "";
}
- 在这里,指定
cron
为0/2 * * * * ?
,表示每间隔2秒进行执行 - 注:
cron
支持读取配置文件
-
cron
表达式格式,我们可以参考Spring官方的调度示例进行学习
┌────────────── 秒 (0-59)
│ ┌───────────── 分钟 (0 - 59)
│ │ ┌───────────── 小时 (0 - 23)
│ │ │ ┌───────────── 一个月中的某天 (1 - 31)
│ │ │ │ ┌───────────── 月(1-12)(或JAN-DEC)
│ │ │ │ │ ┌───────────── 星期几(0 - 7)
│ │ │ │ │ │ (0 或 7 为星期日,或 MON-SUN)
│ │ │ │ │ │
* * * * * *
结论
- Scheduler调度是核心模块,不需要添加其他依赖
- 默认情况下不开启调度,需要使用
@EnableScheduling
显示开启 - 结合
@ConditionalOnProperty
设置是否开启或禁用调度任务 - 被
@Scheduled
注解的方法,表示开启定时任务 fixedRate
或fixedDelay
设置执行间隔initialDelay
设置第一次方法执行的延迟时间
上述的代码示例都已上传到Gitee
参考文章:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)