spring boot 实现启用定时任务

spring boot 整合 scheduled 实现定时任务

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

启用定时任务的注解

定时任务的启动需要添加注解 @EnableScheduling 来启用,如果不添加这个注解则无法启动,添加的位置不固定

@SpringBootApplication
@EnableScheduling
public class ScheduledApplication {

    public static void main(String[] args) {
        SpringApplication.run(ScheduledApplication.class, args);
    }
}

定义定时任务

在项目中如果启用的定时任务的配置后,需要在要启动的定时任务的方法上添加注解 @Scheduled 标识定时任务,该注解可以使用在注解和方法上,不能使用在类上。
@Scheduled注解定义了三种策略是实现延时任务的方式。部分源码如下:

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {

    /**
     * 通过cron 表达式进行定时任务设置,比较灵活
     */
    String cron() default "";

    /**
     * 按照固定延迟周期执行,指的是两次任务执行之间的间隔,在上一次任务执行结束开始计算固定延时时间,后才开始执行任务,如果上一次任务阻塞,会造成下一次任务也执行时间较晚
     */
    long fixedDelay() default -1;

    /**
     * 按照固定频率执行,指的是两次任务开始时间的间隔,在上一次任务执行开始后进行计时,到达执行时间后开始执行下一次任务,但是在上一次任务执行可能还没完成
     */
    long fixedRate() default -1;

    /**
     * 在项目启动后多久时间后才开始执行定时任务
     */
    long initialDelay() default -1;

    /**
     * 时间单位,默认为秒
     * @return
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}

通过@Scheduled注解可知,定时任务时间设置可以通过三种策略设置:fixedRate,fixedDelay,cron
三种方式,其中cron方式设置定时任务比较灵活。

  • fixedRate 适用于需要严格维持任务执行速率、即使前一个任务未结束也应启动下一个任务的场景,但可能引发并发问题。
  • fixedDelay 适用于不希望任务之间相互干扰、需要等待前一个任务完全结束再开始下一个任务的场景,避免了并发问题。
  • cron 适用于需要按照复杂、非固定间隔执行任务的场景,提供高度的定时策略定制能力
public class ScheduledTask {


    /**
     * 定时任务执行
     */
    @Scheduled(cron = "* 0/10 * * * ? ")
    public void fiveSecondPrint() {
        try {
            log.info("cron每十分钟执行一次任务:{}-{}", LocalTime.now(), new Random().nextInt(10));
        } catch (Exception e) {
            // 如果定时任务执行出错进行处理
        }
    }


    /**
     * 固定频率执行定时任务(执行多次),会以上次任务为执行开始时间之间保持恒定的间隔。
     */
    @Scheduled(initialDelay = 1, fixedRate = 1, timeUnit = TimeUnit.HOURS)
    public void fixedRate() {
        try {
            log.info("fixedRate每一小时执行一次任务:{}-{}", LocalTime.now(), new Random().nextInt(100));
        } catch (Exception e) {
            // 如果定时任务执行出错进行处理
        }
    }


    /**
     * 以上一次任务完成开始计算固定间隔后开始执行任务,如果上一次任务完成耗时较长,下一个任务会相应的延迟,始终确保两次任务之间有指定的间隔。
     */
    @Scheduled(initialDelay = 1, fixedDelay = 5, timeUnit = TimeUnit.MINUTES)
    public void fixedDelay() {
        try {
            log.info("fixedDelay执行一次任务:{}-{}", LocalTime.now(), new Random().nextInt(100));
        } catch (Exception e) {
            // 如果定时任务执行出错进行处理
        }
    }


}

定时任务相关配置

定时任务执行使用的异步的方式进行,默认的线程池大小为1,但是可以根据实际情况进行配置实现,扩展线程池容量,线程池名称以及其他配置,实现方式有两种方式分别为:

  • 配置文件实现配置
  • 配置类实现配置
配置文件实现日志相关配置
# 定时任务线程池设置
spring:
  task:
    scheduling:
      # 定时任务线程池的默认大小配置
      pool:
        size: 5
      # 定时任务线程池中线程名称的前缀
      thread-name-prefix: custom-scheduling-
      # 关闭策略
      shutdown:
        await-termination: true
配置类实现定时任务线程池配置
public class CustomerScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(scheduledExecutor());
    }

    /**
     * 自定义线程池
     *
     * @return
     */
    @Bean
    public ThreadPoolTaskScheduler scheduledExecutor() {
        ThreadPoolTaskScheduler taskExecutor = new ThreadPoolTaskScheduler();
        // 核心线程数
        taskExecutor.setPoolSize(2);
        // 线程池的名称前缀
        taskExecutor.setThreadNamePrefix("custom-schedule-");
        // 设置拒绝策略
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        // 设置线程池关闭策略,等待线程池中的所有任务执行完毕
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.initialize();
        return taskExecutor;
    }
}

通过以上两种方式都可以实现对定时任务线程池进行自定义配置,比较推荐使用配置类的方式进行自定义定时任务的配置,可以进行自定义的配置项有很多,更加方便扩展更多的配置项,而配置类可以进行自定义配置的选项较少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr丶李先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值