美文网首页
Spring Boot之使用Scheduled注解实现定时任务

Spring Boot之使用Scheduled注解实现定时任务

作者: Java柱柱 | 来源:发表于2020-07-23 21:10 被阅读0次

    在程序开发的过程中,经常会使用到定时任务来实现一些功能,比如:

    系统依赖于外部系统的非核心数据,可以定时同步(每天同步一次)
    系统内部一些非核心数据的统计计算,可以定时计算(每天计算一次)
    在Spring Boot中,我们可以使用@Scheduled注解来快速的实现定时任务。
    

    @Scheduled注解主要支持以下3种方式:

    fixedRate 固定频率
    fixedDelay 固定延迟
    cron 自定义cron表达式
    

    那么接下来,我们讲解下具体的实现方式。
    fixedRate

    首先,需要在启动类上添加@EnableScheduling注解:

    package com.zwwhnly.springbootdemo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @SpringBootApplication
    @EnableScheduling
    public class SpringbootdemoApplication {
        
        /*其他代码*/
        
        public static void main(String[] args) {
            SpringApplication.run(SpringbootdemoApplication.class, args);
        }
    }
    
    然后,新建一个定时任务测试类TestSchedule,该类需要添加注解@Component,
    最后,添加一个测试方法,该方法添加注解@Scheduled,为了能看到效果,我们每隔5秒输出下系统的当前时间,如下所示:
    
    package com.zwwhnly.springbootdemo;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    @Component
    public class TestSchedule {
        private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        // 每5秒执行一次
        @Scheduled(fixedRate = 5000)
        public void testFixedRate() {
            System.out.println("当前时间:" + simpleDateFormat.format(new Date()));
        }
    }
    

    但是在实际项目中,不可能这么规律,比如方法的执行时间超过了5秒呢(这个应该很常见),那么彼时程序又是如何执行的呢?
    我们先来修改下程序,让方法的执行时间超过5秒:

    // 每5秒执行一次
    @Scheduled(fixedRate = 5000)
    public void testFixedRate() {
        System.out.println("当前时间:" + simpleDateFormat.format(new Date()));
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

    现在是每6秒输出一次时间,由此我们可以得出结论:

    如果方法的执行时间超过了定义的固定频率(比如5秒),那么上一次任务执行完成后,会立即执行下一次任务。
    fixedDelay

    添加一个新方法testFixedDelay,这里我们使用fixedDelay:

    // 上次任务执行结束时间与下次任务执行开始的间隔时间为5s
    @Scheduled(fixedDelay = 5000)
    public void testFixedDelay()
    {
       System.out.println("当前时间:" + simpleDateFormat.format(new Date()));
    }
    

    也许你会很疑惑,这不是和fixedRate的运行结果一样嘛,也是每隔5秒执行一次。
    其实不然,否则Spring Boot怎么会同时支持fixedRate和fixedDelay呢,功能一样,还容易混淆。
    fixedRate与fixedDelay的区别

    为了让你更清晰的看到fixedRate与fixedDelay的区别,我们修改下fixedDelay方法,仍然是让它的执行时间超过5秒:

    // 上次任务执行结束时间与下次任务执行开始的间隔时间为5s
    @Scheduled(fixedDelay = 5000)
    public void testFixedDelay() {
        System.out.println("当前时间:" + simpleDateFormat.format(new Date()));
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

    现在两次输出时间的间隔为11秒,由此我们可以得出结论:
    使用fixedDelay,上一次任务执行完成后,会延迟5秒再执行下一次任务。看到这里,是不是明白了fixedRate与fixedDelay的区别呢,通俗讲就是:

    fixedRate是固定频率执行,fixedDelay是延迟固定时间执行。
    

    cron

    相比于上面讲的两种方式,cron表达式显得更加灵活,因为它基本满足各种场景的配置需求,比如固定频率执行,固定某个时间点执行等。
    首先,我们使用cron表达式实现上述例子中的每隔5秒执行一次:

    @Scheduled(cron = "0/5 * * * * ?")
    public void testCron() {
        System.out.println("当前时间:" + simpleDateFormat.format(new Date()));
    }
    

    手动设置方法的执行时间超过5秒:

    @Scheduled(cron = "0/5 * * * * ?")
    public void testCron() {
        System.out.println("当前时间:" + simpleDateFormat.format(new Date()));
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

    欢迎关注微信公众号【慕容千语】

    相关文章

      网友评论

          本文标题:Spring Boot之使用Scheduled注解实现定时任务

          本文链接:https://www.haomeiwen.com/subject/yukklktx.html