Springboot 不同定时任务实现及场景

实现1、通过开启@EnableScheduling 及注解@Scheduled 实现定时执行任务,【在启动后无法修改定时执行周期】

【完整示例】

package org.javatrip.springboottimer;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@EnableScheduling
public class ScheduledTasks {

//   @Scheduled(cron = "*/50 * * * * ?") // 每小时执行一次
    @Scheduled(fixedRate = 50000, initialDelay = 5000,fixedDelay = 5000)
    public void executeEveryHour() {
        System.out.println("定时器被触发: " + new Date());
    }
}

有两种方式为不同场景【在启动后无法修改定时执行周期】

  • 配置Cron表达式,@Scheduled(cron = “* */50 * * * ?”)

建议:直接点击在线Cron表达式生成器生成参数比较方便:https://www.matools.com/cron/
**【注意】**Cron表达式的开始执行时机,为表达式对应的,系统执行时间所对应的cron表达式时间,
如:每5分钟执行一次,当前系统时间为 10:03分,则定时器开始执行为 10:05执行

  • 固定频率执行@Scheduled(fixedRate = 50000, initialDelay = 5000,fixedDelay = 5000)
    该方式可以设置在系统启动后立即执行,也可延迟执行

实现2、通过开启@EnableScheduling及实现接口 SchedulingConfigurer 完成定时执行任务【在启动后无法修改定时执行周期】

完整示例

package org.javatrip.springboottimer;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@EnableScheduling
@Configuration
public class QuartzSchedulerTask implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 设置可变定时器
        String cors = "0/5 * * * * ?";
        // 注册方式1
        taskRegistrar.addCronTask(() -> {System.out.println("SchedulingConfigurer cron task");}, cors);
        // 注册方式2
        taskRegistrar.addCronTask(new Runnable() {
            @Override
            public void run() {
                System.out.println("SchedulingConfigurer cron task");
            }
        }, cors);

		// 注册方式3,可实现动态修改
        taskRegistrar.addTriggerTask(() -> {
            System.out.println("SchedulingConfigurer cron task" + LocalDateTime.now().toString());
        }, triggerContext -> {
            System.out.println("=====SchedulingConfigurer cron task");

//              return new CronTrigger(cors).nextExecutionTime(triggerContext).toInstant();
                return new PeriodicTrigger(5000).nextExecutionTime(triggerContext).toInstant();
            }
        );
    }
}

这个使用场景主要可以实现创建多种不同的定时器
注册不同的定时器
在这里插入图片描述

**【注意】**实现1、实现2都是只能创建一次性的固定定时器。注册方式3中可实现动态修改

实现3、通过配置@Bean 的TaskScheduler 并采用任务线程池的方式实现多线程任务定时器【可以动态修改定时器执行周期(先删除再新增方式)】

完整示例

创建配置类

package org.javatrip.springboottimer.threadpool;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
public class SchedulerConfig {

    @Bean
    public TaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
            taskScheduler.setPoolSize(10);
            taskScheduler.setThreadNamePrefix("task-scheduler-");
        return taskScheduler;
    }
}

创建业务定时器

package org.javatrip.springboottimer.threadpool;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.concurrent.ScheduledFuture;

@Component
public class MyDynamicTask {

    @Autowired
    private TaskScheduler taskScheduler;

    private ScheduledFuture<?> scheduledFuture;

    // 固定的时间间隔执行
    public static void startTask_FixedRate_period(long interval) {
        if (scheduledFuture != null){
            scheduledFuture = taskScheduler.scheduleAtFixedRate(() -> {
                System.out.println("run task FixedRate" + LocalDateTime.now().toString());
            }, Duration.ofSeconds(5));
        }
    }
    // 指定时间开始固定间间隔执行
    public void startTask_FixedRate_Duration(long interval) {
        if (scheduledFuture != null){
            scheduledFuture = taskScheduler.scheduleAtFixedRate(() -> {
                System.out.println("run task FixedRate" + LocalDateTime.now().toString());
            },LocalDateTime.now().toInstant(ZoneOffset.of("+8")), Duration.ofSeconds(5));
        }
    }

    // 固定的时间点执行
    public void startTask_Instance(long interval) {
        if (scheduledFuture != null){
            scheduledFuture = taskScheduler.schedule(() -> {
                System.out.println("run task FixedRate" + LocalDateTime.now().toString());
            }, LocalDateTime.now().toInstant(ZoneOffset.of("+8")) );
        }
    }
	// 创建周期Cron定时器
    public void startTask_CronTrigger() {
        if (scheduledFuture != null){
            scheduledFuture = taskScheduler.schedule(() -> {
                System.out.println("run task FixedRate" + LocalDateTime.now().toString());
            },  new CronTrigger("0/5 0 * * * ?"));
        }
    }

	// 创建固定周期定时器
    public void startTask_PeriodicTrigger(long interval) {
        if (scheduledFuture != null){
            scheduledFuture = taskScheduler.schedule(() -> {
                System.out.println("run task FixedRate" + LocalDateTime.now().toString());
            },  new PeriodicTrigger(interval));
        }
    }
	// 停止删除定时器
    public void stopTask() {
        if (scheduledFuture != null){
            scheduledFuture.cancel(true);
        }
    }
}

业务使用定时器

在需要的方法中执行 MyDynamicTask.startTask的开启方法,进行开启一个定时器。
当停止定时器时可以通过调用  MyDynamicTask.stopTask.
当需要修改时,1、先调用  MyDynamicTask.stopTask.停止之前的 2、再 MyDynamicTask.startTask的开启新的

**【注意】**该示例中TaskScheduler 采用的是ThreadPoolTaskScheduler 线程池的方式,这样有利于处理高并发场景下的多任务定时器。
同时TaskScheduler接口 还有其他不同的实现类,可以在不同的场景下使用。
在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值