任务调度(1)-Spring @Scheduled详解

Spring3.0版本之后提供了@EnableScheduling和@Scheduled来进行定时任务的功能。

使用Spring创建定时任务非常简单,我们可以使用如下两种方式(当然不仅仅只包括这两种):

  1. 基于注解(@Scheduled)
  2. 基于接口(SchedulingConfigurer),这里可以自定义线程池的线程数和动态设置定时任务的属性

1. 基于注解的实现如下:

首先在Spring启动类添加注解@EnableScheduling

@SpringBootApplication
@EnableScheduling
public class SpringMain {
    public static void main(String[] args) {
        // ...
    }
}

下面是@EnableScheduling的源码(省略注释):

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {

}

其次在我们需要实现任务调度的地方添加@Scheduled注解

@Component
public class Jobs {
    
    @Scheduled(fixedRate = 1000)
    public void fixedRateJob() {
        // ...
    }
    
    
    @Scheduled(fixedDelay = 1000)
    public void fixedDelayJob() {
        // ...
    }
    
    
    @Scheduled(initialDelay = 1000)
    public void initDelayJob() {
        // ...
    }
    
    
    @Scheduled(cron = "0/1 * * * * ? ")
    public void cronJob() {
        // ...
    }
    
    @Scheduled(fixedDelayString = "")
    public void fixedDelayStringJob() {
        // ...
    }

    @Scheduled(fixedRateString = "")
    public void fixedRateStringJob() {
        // ...
    }

    @Scheduled(initialDelayString = "")
    public void initDelayStringJob() {
        // ...
    }

    @Scheduled(zone = "")
    public void zoneJob() {
        // ...
    }
}

下面是@Scheduled的源码(省略注释,添加解释):

   
   // cron表达式
   // 可以去 [Cron - 在线Cron表达式生成器 (ciding.cc)](http://cron.ciding.cc/) 查看
   String cron() default "";
   
   // 时区,一般留空
   String zone() default "";
   
   // 上一次执行完毕时间点之后多长时间再执行,单位是毫秒
   long fixedDelay() default -1;

   // 与fixedDelay一样,只是使用了字符串的形式,可以支持占位符
   String fixedDelayString() default "";

   // 上一次开始执行时间点之后多长时间再执行,单位是毫秒
   long fixedRate() default -1;

   // 与fixedRate一样,只是使用字符串的形式,可以支持占位符
   String fixedRateString() default "";

   // 第一次延迟多长时间后再执行
   long initialDelay() default -1;

    // 与initialDelay一样,只是使用字符串的形式,可以支持占位符
   String initialDelayString() default "";

2. 基于接口(SchedulingConfigurer),这里可以自定义线程池的线程数和动态设置定时任务的属性

为什么基于接口去实现,因为通过查看Spring的源码,发现Spring提供的任务调度是创建了只有一个线程数的线程池。

具体代码如下:

    if (this.taskScheduler == null) {
        this.localExecutor = Executors.newSingleThreadScheduledExecutor();
        this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
    }

这样就会带来一些问题,比如假设我们有个调度任务A,每次执行的时间间隔是5分钟,但是这个调度任务A执行的时间会大于5分钟,因为只有一个线程在执行任务,那么本来5分钟之后应该再次执行的任务会产生延迟,会产生任务无法执行的错觉。

所以我们这里可以通过实现Spring提供的SchedulingConfigurer接口来设置:

  1. 自定义线程池
  2. 动态添加任务和修改任务属性

代码如下:

    @Configuration
    public class DynamicScheduleConfigurer implements SchedulingConfigurer
    {
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
        {
            // 1. 自定义Scheduler
            // ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
            // taskScheduler.setPoolSize(50);
            // taskRegistrar.setTaskScheduler(taskScheduler);
            
            // 2. 添加任务,修改属性
            taskRegistrar.addTriggerTask(
                    // 添加定时任务
                    () -> System.out.println("xxx"),
                    // 设置执行周期(Trigger)
                    triggerContext -> {
                        String cron = "0/5 * * * * ? *";
                        return new CronTrigger(cron).nextExecutionTime(triggerContext);
                    }
            );
        }
}

通过实现这个方法,我们可以将任务的信息放在数据库当中,当程序启动的时候读取数据库任务的信息进行任务的添加,运行时更改任务的信息。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring的@Scheduled是一个注解,用于在Spring应用程序中实现任务调度和异步方法执行。它提供了对基于cron表达式的任务调度的支持,并可以与触发器元数据一起添加到方法中。使用@Scheduled注解,可以指定方法在何时执行以及执行的频率。\[1\] 要在Spring应用程序中使用@Scheduled注解,需要在应用程序的配置文件中添加相应的命名空间和模式。例如,在applicationConfig.xml文件中,可以添加以下配置来引入task命名空间和模式:xmlns:task="http://www.springframework.org/schema/task" http://www.springframework.org/schema/task/ http://www.springframework.org/schema/task/spring-task-3.0.xsd\[2\] 使用@Scheduled注解的方法应该没有任何参数,并且不应该返回任何值。如果需要在@Scheduled方法中使用外部对象,应该使用自动装配将它们注入到相应的类中,而不是将它们作为参数传递给@Scheduled方法。\[3\] 总结起来,@Scheduled是Spring框架中用于任务调度和异步方法执行的注解,它可以与cron表达式一起使用,并提供了灵活的任务调度功能。 #### 引用[.reference_title] - *1* *2* *3* [Spring @Scheduled 使用详解](https://blog.csdn.net/DynmicResource/article/details/124013028)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值