说明

  • 启动类添加注解 @EnableScheduling ,任务方法添加注解 @Scheduled ,共同配合实现定时任务
  • 定时任务的线程池默认大小为 1,也就是单线程执行,这个 poolSizeThreadPoolTaskScheduler.java 中定义
  • 如果有多个定时任务,默认为串行执行。要实现并发执行,则必须修改线程池大小。
    • 方式一:配置线程池大小(推荐)

      • application.yml 中配置
      1
      2
      3
      4
      5
      6
      spring:
      task:
      scheduling:
      pool:
      size: 20 # 配置线程池大小,默认为 1,单线程
      thread-name-prefix: Job-Thread-
      • 或者通过代码配置
      1
      2
      3
      4
      5
      6
      7
      @Configuration
      public class SchedulerConfig implements SchedulingConfigurer {
      @Override
      public void configureTasks(ScheduledTaskRegistrar registrar) {
      registrar.setScheduler(Executors.newScheduledThreadPool(10)); // 10线程池
      }
      }
    • 方式二:结合 @Async 实现异步执行

      为任务添加 @Async 注解,使同一任务的不同实例也能并行执行。需先配置异步线程池:

      • 配置类方式

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        @Configuration
        @EnableAsync
        public class AsyncConfig {
        @Bean
        public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10); // 核心线程数
        executor.setMaxPoolSize(50); // 最大线程数
        executor.setQueueCapacity(100); // 队列容量
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
        }
        }
      • 配置文件方式

        1
        2
        3
        4
        spring.task.execution.pool.core-size=10
        spring.task.execution.pool.max-size=50
        spring.task.execution.pool.queue-capacity=100
        spring.task.execution.thread-name-prefix=Async-

示例

添加注解 @Scheduled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* <p>
* 定时任务
* </p>
*
* @author yangkai.shen
* @date Created in 2018-11-22 19:09
*/
@Component
@Slf4j
public class TaskJob {

/**
* 按照标准时间来算,每隔 10s 执行一次
*/
@Scheduled(cron = "0/10 * * * * ?")
public void job1() {
log.info("【job1】开始执行:{}", DateUtil.formatDateTime(new Date()));
}

/**
* 从启动时间开始,间隔 2s 执行
* 固定间隔时间
*/
@Scheduled(fixedRate = 2000)
public void job2() {
log.info("【job2】开始执行:{}", DateUtil.formatDateTime(new Date()));
}

/**
* 从启动时间开始,延迟 5s 后间隔 4s 执行
* 固定等待时间
*/
@Scheduled(fixedDelay = 4000, initialDelay = 5000)
public void job3() {
log.info("【job3】开始执行:{}", DateUtil.formatDateTime(new Date()));
}
}

参考文档