• 理解ScheduledExecutorService中scheduleAtFixedRate和scheduleWithFixedDelay的区别


    scheduleAtFixedRate

    每间隔一段时间执行,分为两种情况:

    1. 当前任务执行时间小于间隔时间,每次到点即执行;

      /**
       * 任务执行时间(8s)小于间隔时间(10s)
       */
      public class ScheduleTest {
          static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
      
          public static void main(String[] args) {
              scheduler.scheduleAtFixedRate(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("Start: scheduleAtFixedRate:    " + new Date());
                      try {
                          Thread.sleep(8000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println("End  : scheduleAtFixedRate:    " + new Date());
                  }
              }, 0, 10 , SECONDS);
          }
      }
      
      output:
      
      Start: scheduleAtFixedRate:    Sun Apr 28 14:36:00 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:36:08 CST 2019
      Start: scheduleAtFixedRate:    Sun Apr 28 14:36:10 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:36:18 CST 2019
      Start: scheduleAtFixedRate:    Sun Apr 28 14:36:20 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:36:28 CST 2019
      Start: scheduleAtFixedRate:    Sun Apr 28 14:36:30 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:36:38 CST 2019
      ...
          
      程序启动时间是14:36:00,以后每间隔10s执行一次(即14:36:10、14:36:20、14:36:30等)。
      
    2. 当前任务执行时间大于等于间隔时间,任务执行后立即执行下一次任务。相当于连续执行了。

      /**
       * 任务执行时间(12s)大于间隔时间(10s)
       */
      public class ScheduleTest {
          static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
      
          public static void main(String[] args) {
              scheduler.scheduleAtFixedRate(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("Start: scheduleAtFixedRate:    " + new Date());
                      try {
                          Thread.sleep(12000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println("End  : scheduleAtFixedRate:    " + new Date());
                  }
              }, 0, 10 , SECONDS);
          }
      }
      
      output:
      
      Start: scheduleAtFixedRate:    Sun Apr 28 14:30:13 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:30:25 CST 2019
      Start: scheduleAtFixedRate:    Sun Apr 28 14:30:25 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:30:37 CST 2019
      Start: scheduleAtFixedRate:    Sun Apr 28 14:30:37 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:30:49 CST 2019
      Start: scheduleAtFixedRate:    Sun Apr 28 14:30:49 CST 2019
      End  : scheduleAtFixedRate:    Sun Apr 28 14:31:01 CST 2019
          
      程序启动时间是14:30:13,按理说应该每间隔10s执行一次(即14:30:23、14:30:33等),但由于任务执行时间长于10s,下一次的任务要开始的时候发现上次的任务还没有完成,因此阻塞等待,一旦发现上次的任务完成,就马上启动。表现出来就是任务延时启动,最终的效果就是连续执行。
      

    scheduleWithFixedDelay

    每当上次任务执行完毕后,间隔一段时间执行。不管当前任务执行时间大于、等于还是小于间隔时间,执行效果都是一样的。

    /**
     * 任务执行时间(8s)小于间隔时间(10s)
     */
    public class ScheduleTest {
        static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
        public static void main(String[] args) {
            scheduler.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Start: scheduleWithFixedDelay: " + new Date());
                    try {
                        Thread.sleep(12000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("End  : scheduleWithFixedDelay: " + new Date());
                }
            }, 0, 10 , SECONDS);
        }
    }
    
    output:
    
    Start: scheduleWithFixedDelay: Sun Apr 28 14:27:59 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:28:07 CST 2019
    Start: scheduleWithFixedDelay: Sun Apr 28 14:28:17 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:28:25 CST 2019
    Start: scheduleWithFixedDelay: Sun Apr 28 14:28:35 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:28:43 CST 2019
    Start: scheduleWithFixedDelay: Sun Apr 28 14:28:53 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:29:01 CST 2019
    ...
    
    可以看出每个End后,等待了10秒,才启动下一次Start。
    
    /**
     * 任务执行时间(12s)大于间隔时间(10s)
     */
    public class ScheduleTest {
        static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
        public static void main(String[] args) {
            scheduler.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Start: scheduleWithFixedDelay: " + new Date());
                    try {
                        Thread.sleep(12000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("End  : scheduleWithFixedDelay: " + new Date());
                }
            }, 0, 10 , SECONDS);
        }
    }
    
    output:
    
    Start: scheduleWithFixedDelay: Sun Apr 28 14:26:29 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:26:41 CST 2019
    Start: scheduleWithFixedDelay: Sun Apr 28 14:26:51 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:27:03 CST 2019
    Start: scheduleWithFixedDelay: Sun Apr 28 14:27:13 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:27:25 CST 2019
    Start: scheduleWithFixedDelay: Sun Apr 28 14:27:35 CST 2019
    End  : scheduleWithFixedDelay: Sun Apr 28 14:27:47 CST 2019
    ...
    
    可以看出每个End后,等待了10秒,才启动下一次Start。
    

    参考

    scheduleAtFixedRate vs scheduleWithFixedDelay

    扩展

    Spring定时任务@Scheduled注解使用方式浅窥(cron表达式、fixedRate和fixedDelay)

  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/xiaoxi666/p/10783879.html
Copyright © 2020-2023  润新知