spring · 2022-01-30 0

Spring的@EnableScheduling和@Scheduled的使用

一、概述

@EnableScheduling 配置在配置类上,表示对定时任务的支持

@Scheduled 配置在方法上,声明需要执行定时任务的方法

二、@Scheduled 参数

  1. zone表示执行时间时区
  2. initialDelay 和initialDelayString表示初始延迟时间,第一次被调用前延迟的时间
  3. fixedRate 和fixedRateString表示固定频率,上个任务开始后,多长时间后开始执行
  4. fixedDelay 和fixedDelayString 表示固定延迟时间,上个任务完成后,延迟多长时间执行
  5. cron是设置定时执行的表达式,表达式对应含义:second、minute、hour、day of month、month、day of week,代表秒、分、时、日、月、星期

三、cron 表达式

如: * */5 * * * SUN-MON 周一至周五每隔5分钟执行一次

可用"-"表示范围;""表示所有的值,其中day of month (日) 和day of week (星期),表达式包含"?"时,整个表达式会被直接替换为""

  1. second:值可为0到59
  2. minute:值可为0到59
  3. hour:值可为0到23
  4. day of month:值可为1到31,可用"-"表示范围
  5. month:值可以1到12,或JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC
  6. day of week:值可为0到6,或SUN(0, 7),MON,TUE,WED,THU,FRI,SAT

四、栗子

pom文件:

<properties>
    <spring.version>5.1.9.RELEASE</spring.version>
</properties>

<dependencies>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.version}</version>
    </dependency>

</dependencies>

代码:

@Configuration
@EnableScheduling
public class SchedulingConfig {

    /**
     * 配置 taskScheduler,多线程执行多个任务;
     * 如果不配置taskScheduler,默认使用的是容量为1的线程池
     */
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setThreadNamePrefix("my-task-scheduler-");
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }

    @Scheduled(initialDelay = 3000, fixedRate = 5000)
    public void fixedRate() {
        String threadName = Thread.currentThread().getName();
        System.out.println(String.format("%s ===>初始延迟3s,每隔5s", threadName));
    }

    @Scheduled(fixedDelay = 5000)
    public void fixedDelay() {
        String threadName = Thread.currentThread().getName();
        System.out.println(String.format("%s ==>每次执行完延迟5秒", threadName));
    }

    @Scheduled(cron = "5 * * * * *")
    public void second1() {
        String threadName = Thread.currentThread().getName();
        System.out.println(String.format("%s ===>在5s的时候执行", threadName));
    }

    @Scheduled(cron = "*/5 * * * * *")
    public void second2() {
        String threadName = Thread.currentThread().getName();
        System.out.println(String.format("%s ===>每5s执行一次", threadName));
    }
}

五、原理

任务会被注册到org.springframework.scheduling.config.ScheduledTaskRegistrar

默认会创建线程池Executors.newSingleThreadScheduledExecutor(),其容量为1,所以默认就一个线程执行任务

如果需要多线程执行多个任务,需要配置 TaskScheduler