Java - 從簡單例子看ScheduledExecutorService兩個方法差異:scheduleWithFixedDelay() vs. scheduleAtFixedRate()

先前情提要一下:JDK5開始提供ScheduledExecutorService讓我們能做工作排程。之前是由java.util.Timer和java.util.TimerTask做工作排程,不過限制會較多。

其中scheduleWithFixedDelay()和scheduleAtFixedRate()差別一開始難從文字理解,以下就直接從例子中分辨兩者吧:


scheduleWithFixedDelay() :當希望delay時間是1 sec時,則下個執行時間,會是上個執行時間+delay時間,在例子中會是2+1=3 sec為間隔執行一次。

e.g. 
package my11Test;

/**
 *
 * @author lucrecialin
 */

import java.util.concurrent.*;
public class ScheduleWithFixedDelaySample {
    public static void main(String[] args) {
        ScheduledExecutorService myTimer
                = Executors.newSingleThreadScheduledExecutor();
        
        myTimer.scheduleWithFixedDelay(
                () -> {
                    System.out.println(new java.util.Date());
                    try {
                        Thread.sleep(2000);
                    
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }, 2, 1, TimeUnit.SECONDS);
    }
}

下面為編譯結果:




scheduleAtFixedRate():當希望delay時間是1 sec時,有兩種執行結果:
    case 1: 因執行時間為2 sec,大於delay時間的1 sec,因而「當執行時間大於指定週期」時,當上個執行完,就會馬上接著執行下一個,在例子中會是2 sec為間隔執行一次。

e.g. 
package my11Test;

/**
 *
 * @author lucrecialin
 */

import java.util.concurrent.*;
public class ScheduleAtFixedRateSample {
    public static void main(String[] args) {
        ScheduledExecutorService myTimer
                = Executors.newSingleThreadScheduledExecutor();
        
        myTimer.scheduleAtFixedRate(
                () -> {
                    System.out.println(new java.util.Date());
                    try {
                        Thread.sleep(2000);
                    
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }, 2, 1, TimeUnit.SECONDS);
    }
}

下面為編譯結果:



    case 2: 因執行時間為0.5 sec,小於delay時間的1 sec,因而「當執行時間未超過指定週期」時,在例子中會是1 sec為間隔執行一次。

e.g. 
package my11Test;

/**
 *
 * @author lucrecialin
 */

import java.util.concurrent.*;
public class ScheduleAtFixedRateSample {
    public static void main(String[] args) {
        ScheduledExecutorService myTimer
                = Executors.newSingleThreadScheduledExecutor();
        
        myTimer.scheduleAtFixedRate(
                () -> {
                    System.out.println(new java.util.Date());
                    try {
                        Thread.sleep(500);
                    
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }, 2, 1, TimeUnit.SECONDS);
    }
}

下面為編譯結果:

留言

熱門文章