分布式调度器--Spring Task 的使用

时间:2024-10-20 22:25:58

目录

1、启动类(App.java)上加@EnableScheduling注解: 开启基于注解的任务调度器

2、同步定时任务

3、多线程(异步)定时任务

3.1 配置线程池

3.2 开启异步支持

3.3 定义异步方法

4、Api说明

4.1 fixedDelay

4.2 fixedRate

4.3 initialDelay

4.4 cron(掌握)

cron表达式

① 格式

② 特殊符号

③ 练习

标准格式: * * * * * ?


Spring Task是 Spring 框架的一个组件,它为任务调度提供了支持,使开发者能 创建后台任务 定期执行任务

1、启动类(App.java)上加@EnableScheduling注解: 开启基于注解的任务调度器

默认情况下,系统会自动启动一个线程,调度执行项目中定义的所有定时任务

这个注解 是SpringBoot内置的 不需要依赖任何的starter包

2、同步定时任务

需要在定时执行的方法上 添加@Scheduled注解

定时执行的方法不能有参数,并且一般没有返回值

定时任务所在的类要作为 Spring Bean,在类上添加@Component注解即可,即:定时方法所在的类,要放到IOC容器里面

注意:使用@Scheduled注解形式的定时任务,默认是单线程来执行项目中所有的定时任务。

即使如果同一时刻有两个定时任务需要执行,那么只能其中一个定时任务完成之后再执行下一个定时任务。

如果项目只有一个定时任务还好。若定时任务增多时,如果一个任务被阻塞,则会导致其他任务无法正常执行。

若要改变这种行为,使得定时任务能够并发执行,可以配置任务调度线程池,来解决以上问题。首先配置一个线程池

package com.***.springtask;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@EnableAsync //开启异步支持
@EnableScheduling //开启定时任务支持
public class ScheduledTask {

    int i = 1;
    //@Scheduled(fixedRate = 5000, initialDelay = 15*1000)
    public void task1(){
//        i++;
//        if(i > 5){
//            ThreadUtil.safeSleep(8*1000);
//        }
        log.debug("task1执行了{}次,{}",i,Thread.currentThread().getId());
    }

    @Scheduled(cron = "0/5 * * * * ?")
    @Async("asyncScheduledPool")
    public void task2(){

        // ThreadUtil.safeSleep(8*1000);
        log.debug("task2执行了,{}",Thread.currentThread().getId());

    }

}

3、多线程(异步)定时任务

3.1 配置线程池

package com.***.config;

import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Component
public class ExecutorConfig {
    //定义核心线程数
    public static final  int CORE_POOL_SIZE = 10;
    // 最大线程数
    public static final  int MAX_POOL_SIZE = 20;
    // 任务队列容量大小
    public static final  int QUEUE_MAX_COUNT = 100;

    @Bean("asyncScheduledPool")
    public Executor asyncScheduledPool(){
        //自定义线程池
        ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        threadPoolExecutor.setCorePoolSize(CORE_POOL_SIZE);
        //设置最大线程数 : 长工 +  临时工
        threadPoolExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        //设置任务队列容量大小
        threadPoolExecutor.setQueueCapacity(QUEUE_MAX_COUNT);
        //设置线程的名称前缀
        threadPoolExecutor.setThreadNamePrefix("myTask-");
        //设置拒绝策略
        threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        return  threadPoolExecutor;
    }

}

3.2 开启异步支持

要在 Spring Boot 应用中启用异步方法调用,需在启动类上添加 @EnableAsync 注解

3.3 定义异步方法

在服务类中定义一个方法,并使用 @Async 注解标记它以实现异步执行

4、Api说明

4.1 fixedDelay

@Scheduled(fixedDelay = 4000) 

4.2 fixedRate

@Scheduled(fixedRate = 10000) 

4.3 initialDelay

@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次

4.4 cron(掌握)

cron表达式

① 格式

Seconds Minutes Hours Day Month Week

② 特殊符号

*:任意值
-:范围,eg:3-5指3点到5点执行
,:枚举,eg:3,5指3点和5点执行
/:增量,eg:3/5从第3秒开始每隔5秒执行一次
?:忽略,且只能在 日期域 或 星期域 只用

③ 练习

标准格式: * * * * * ?

周一至周五的上午10:15触发

0 15 10 ? * 2-6

表示在每月的1日的凌晨2点调整任务

0 0 2 1 * ?

朝九晚五工作时间内每半小时

0 0/30 9-16 * * ?

每天上午10点,下午2点,4点

0 0 10,14,16 * * ?

表示每个星期三中午12点

0 0 12 ? * 4

在每天下午2点到下午2:59期间的每1分钟触发

0 /1 14-15 * * ?

在每天下午2点到下午2:05期间的每1分钟触发

0 0-5/1 14 * * ?

在每天下午2点到下午2:55期间的每5分钟触发

0 0-55/5 14 * * ?

在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

0 0-55/5 14,18 * * ?

相关文章