2016-08-11 72 views
3

這裏是我想要的代碼:什麼是java.util.Timer固定延遲週期性任務?

import java.util.Timer; 
import java.util.TimerTask; 

public class PeriodicTask { 

public static void main (String[] args) { 

    System.out.println("Main thread: " + Thread.currentThread()); 
    Timer timer = new Timer(); 
    final long start = System.currentTimeMillis(); 
    timer.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      System.out.print("Timer task invoked in millis: " + 
              (System.currentTimeMillis()- start)); 
      System.out.println(" -- " + Thread.currentThread()); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("task finished "+(System.currentTimeMillis() 
           - start)); 
     } 
    }, 1000,500); 
} 
} 

輸出:

Main thread: Thread[main,5,main] 
Timer task invoked in millis: 1000 -- Thread[Timer-0,5,main] 
task finished 2001 
Timer task invoked in millis: 2001 -- Thread[Timer-0,5,main] 
task finished 3002 
Timer task invoked in millis: 3002 -- Thread[Timer-0,5,main] 
task finished 4002 
Timer task invoked in millis: 4002 -- Thread[Timer-0,5,main] 
...... 

按照java.util.Timer中的文檔所提供的時間段應該在每次任務執行分開。所以我期待每個釣魚任務和新的被調用的任務應該分開500毫秒,例如在第一個任務結束和第二個任務執行開始之間應該是:

task finished 2001 
Timer task invoked in millis: **2501** -- Thread[Timer-0,5,main] 

我錯過了什麼嗎?

我使用JDK 1.8

回答

0

分隔每個任務的period是不是相對於任務的結束,而是它的起點。 Timer將嘗試在period過去之後再次安排任務。除非任務仍在運行,否則將在前一任務完成後立即安排。

在您給出的示例中,您設置了一個Timer,其中period的值爲500ms。您在方法內爲1000ms調用sleep()。這意味着Timer想要在半秒後再次安排任務,但不能完成,因爲之前的任務仍有半秒鐘才能完成。

+0

你的解釋與我的輸出非常一致。我猜Java文檔寫得非常糟糕。例如「在固定延遲執行中,每個執行都按照前一次執行的實際執行時間進行調度」。不知道他們想說什麼。世界「執行」一次使用四次。 – Joe

+0

@Joe是的。我檢查了java文檔,也沒有真正理解它,所以這就是爲什麼我設置了一些測試,並發現這是一致的。另外,如果你不能提出這個問題,你能否將其標記爲正確的。 – Arthur

+0

當然,謝謝你的幫助! – Joe