Spring Boot 2.0 开始对 Quartz 提供了支持,可以通过@Scheduled注解来创建定时任务。

依赖声明:

1
2
3
4
5
6
7
8
9
10
11
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
</dependencies>
spring-boot-starter-quartz:Quartz Scheduler 启动器。

启动类:

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

@EnableScheduling:用于启动定时任务。

@Scheduled(fixedDelay):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package org.fanlychie.core;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
@Component
public class ScheduledTask {
@Scheduled(fixedDelay = 5000)
public void fixedDelayTask() throws InterruptedException {
System.out.println("[fixedDelay] " + LocalDateTime.now());
TimeUnit.MILLISECONDS.sleep(2000);
}
}

fixedDelay:从上一次任务执行完成之后开始计算,间隔多长时间再执行。

运行结果输出:

1
2
3
[fixedDelay] 2018-07-14T14:07:12.877
[fixedDelay] 2018-07-14T14:07:19.878
[fixedDelay] 2018-07-14T14:07:26.879

@Scheduled(fixedRate):

1
2
3
4
5
@Scheduled(fixedRate = 5000)
public void fixedRateTask() throws InterruptedException {
System.out.println("[fixedRate] " + LocalDateTime.now());
TimeUnit.MILLISECONDS.sleep(2000);
}

fixedRate:从上一次任务执行时开始计算,间隔多长时间再执行。

运行结果输出:

1
2
3
[fixedRate] 2018-07-14T14:09:23.248
[fixedRate] 2018-07-14T14:09:28.230
[fixedRate] 2018-07-14T14:09:33.229

@Scheduled(initialDelay):

1
2
3
4
5
@Scheduled(initialDelay = 2000, fixedRate = 5000)
public void initialDelayTask() throws InterruptedException {
System.out.println("[initialDelay] " + LocalDateTime.now());
TimeUnit.MILLISECONDS.sleep(2000);
}

initialDelay:计划任务第一次启动时延迟多长时间执行。它通常搭配fixedDelayfixedRate来使用。

运行结果输出:

1
2
3
[initialDelay] 2018-07-14T14:13:31.410
[initialDelay] 2018-07-14T14:13:36.399
[initialDelay] 2018-07-14T14:13:41.312

@Scheduled(cron):

1
2
3
4
5
@Scheduled(cron = "*/5 * * * * ?")
public void cronTask() throws InterruptedException {
System.out.println("[cron] " + LocalDateTime.now());
TimeUnit.MILLISECONDS.sleep(2000);
}

cron:使用「cron表达式」定义计划任务的执行规则。

运行结果输出:

1
2
3
[cron] 2018-07-14T22:07:10.004
[cron] 2018-07-14T22:07:15.001
[cron] 2018-07-14T22:07:20.001

并行执行计划任务

通过@Scheduled配置的计划任务是串行执行的,多个任务之间会相互影响(当一个任务未执行完,另一个任务需要等待)。如果想要避免这个问题,可以采用并行的方式执行任务。

1
2
3
4
5
6
7
8
9
@Configuration
public class ApplicationConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(4));
}
}

newScheduledThreadPool:用于创建一个固定大小的线程池,并且它支持定时或周期性的执行任务。

示例项目开发环境:Java-8、Maven-3、IntelliJ IDEA-2018、Spring Boot-1.5.14.RELEASE
完整示例项目链接:spring-boot-scheduled-sample