13 Spring Boot 定时任务
@EnableScheduling
首先在 SpringBoot 启动类加上 @EnableScheduling 启用定时任务。
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}创建 scheduled task
使用 @Scheduled 注解就能很方便地创建一个定时任务,下面的代码中涵盖了 @Scheduled 的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。
@Slf4j
@Component
public class ScheduledTasks {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
/**
* fixedRate:固定速率执行。每5秒执行一次。
*/
@Scheduled(fixedRate = 5000)
public void reportCurrentTimeWithFixedRate() {
log.info("Current Thread : {}", Thread.currentThread().getName());
log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date()));
}
/**
* fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。
*/
@Scheduled(fixedDelay = 2000)
public void reportCurrentTimeWithFixedDelay() {
try {
TimeUnit.SECONDS.sleep(3);
log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。
*/
@Scheduled(initialDelay = 5000, fixedRate = 5000)
public void reportCurrentTimeWithInitialDelay() {
log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date()));
}
/**
* cron:使用Cron表达式。 每分钟的1,2秒运行
*/
@Scheduled(cron = "1-2 * * * * ? ")
public void reportCurrentTimeWithCronExpression() {
log.info("Cron Expression: The time is now {}", dateFormat.format(new Date()));
}
}注意 fixedRate 模式有个小坑,假如有这样一种情况:某个方法的定时器设定的固定速率是每 5 秒执行一次。这个方法现在要执行下面四个任务,四个任务的耗时是:6 s、6s、2s、3s,请问这些任务默认情况下(单线程)将如何被执行?程序验证:
运行程序输出如下:
示意图:

自定义线程池
默认情况下,@Scheduled 任务都在 Spring 创建的大小为 1 的默认线程池中执行,你可以通过在加了 @Scheduled 注解的方法里加上下面这段代码来验证。
每次运行都会输出:
如果需要自定义线程池执行话只需要新加一个实现 SchedulingConfigurer 接口的 configureTasks 的类即可,这个类需要加上 @Configuration 注解。
并发执行
测试代码:
reportCurrentTimeWithFixedDelay() 方法会每 5 秒执行一次,执行代码输出如下:
添加 @EnableAsync 和 @Async 这两个注解让任务并行执行:
reportCurrentTimeWithFixedDelay() 方法上加上 @Async 注解后会每 2 秒执行一次,执行代码输出如下:
最后更新于
这有帮助吗?