能够让我们在指定的某个时间段自动执行任务,不需要自己去手动触发。
如:定时发送邮件、定时发送优惠卷等…
文章中的代码,保存在Gitee中
默认情况下不开启定时任务,如果想使用添加@EnableScheduling
来显示启动
@SpringBootApplication
@EnableScheduling
public class SpringSchedulerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSchedulerApplication.class, args);
}
}
更好的做法,是定义一个定时器的配置类,在结合@ConditionalOnProperty
控制定时任务的开启和关闭
@Configuration
@EnableScheduling
// 默认为false, 配置为true代表开启定时功能,
@ConditionalOnProperty(name = "scheduler.enabled", matchIfMissing = true)
public class SchedulerConfig {
}
默认单位都为毫秒(ms)
fixedDelay
属性配置定时任务在指定延迟时间后执行
新任务要等待前一个任务完成,示例如下:
@Scheduled(fixedDelay = 2000)
public void computePrice() throws InterruptedException {
log.info("current time: {}", LocalTime.now());
Thread.sleep(4000);
}
每2秒执行一次
在新任务开启前, 需要等待旧任务完成。因此我们可以看到6秒后才会执行下一个任务
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
**调整线程池大小。
使用fixedRate
和fixedDelay
属性,方法的第一次调用,会在上下文初始化完成后通过指定的时间进行调度。
但是可以通过initialDelay
属性,指定第一次方法执行的延迟时间。示例如下:
// 第一次延迟5秒后执行, 后续延迟都为3秒
@Scheduled(initialDelay = 5000, fixedRate = 3000)
@Async
public void refreshPricingParametersTemp() {
log.info("current time: {}", LocalTime.now());
}
可以通过这个文档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);
}
// yaml设置
interval: PT02S
// properties设置
interval=PT02S
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)
│ │ │ │ │ │
* * * * * *
@EnableScheduling
显示开启@ConditionalOnProperty
设置是否开启或禁用调度任务@Scheduled
注解的方法,表示开启定时任务fixedRate
或fixedDelay
设置执行间隔initialDelay
设置第一次方法执行的延迟时间上述的代码示例都已上传到Gitee
参考文章: