zoukankan      html  css  js  c++  java
  • 理解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)

  • 相关阅读:
    mysql
    selenium
    解决servlet响应乱码问题
    flask后端的跨域问题
    python中并发----线程的启动和停止
    react-native 自定义组件规范
    react-native 高阶组件笔记
    class-dump安装及使用
    jekyll的安装
    取巧的json转model声明代码的工具
  • 原文地址:https://www.cnblogs.com/xiaoxi666/p/10783879.html
Copyright © 2011-2022 走看看