使用Java預定執行程序時遇到的一個特點是,想知道我所經歷的是否正常。Java預定執行程序的準確性
我需要安排以5秒預定義速度執行的任務。預計這些任務的執行時間不會超過5秒,但是當它們運行的時間低於5秒時,備份的任務列表應該快速連續運行以趕上。在運行任務時,瞭解原始預定執行時間是什麼很重要(請考慮scheduledExecutionTime()
的java.util.TimerTask
)。最後,我需要跟蹤計劃時間和實際時間之間的差異,以確定計劃何時「漂移」以及計劃多少時間。
到目前爲止,我已經通過使用Java執行人實現這一切,和下面的類說明了總體思路:
public class ExecutorTest {
public static final long PERIOD = 5000;
public static void main(String[] args) {
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
new Command(), 0, PERIOD, TimeUnit.MILLISECONDS);
}
private static final class Command implements Runnable {
long timestamp = 0;
public void run() {
long now = System.currentTimeMillis();
if (timestamp == 0) {
timestamp = now;
}
// Drift is the difference between scheduled time and execution time
long drift = now - timestamp;
String format = "Ran at %1$tF %<tT,%<tL; drift: %2$dms";
System.out.println(String.format(format, now, drift));
timestamp += PERIOD;
}
}
}
運行上述代碼顯示漂移(在理想情況下應儘量靠近0)可能會波動多達幾秒鐘,其結果是執行任務過早或過遲。我創建了一個圖表運行此爲約150分鐘的結果:
所以我的第一個問題是,這是否是正常的。我的環境由32位Windows XP和Java 1.5更新21組成(儘管Java 6 update 22產生了類似的結果)。
第二個問題是是否有簡單的方法來減少漂移量。如果我使用簡單的java.util.Timer
或甚至僅使用Thread.sleep()
,則漂移不存在。
最後,在使用預定的執行程序時,是否有更好的方法來跟蹤預定的執行時間?