關于Timer運行時修改系統時間
對Sun JDK的Timer來說,系統時間修改到當前時間之后,不會影響Timer的執行;但是如果系統時間修改到當前時間之前,就會導致Timer掛起。
下面這段代碼就是根本原因了(取自sun jdk1.4.2 source code, java.util.Timer#mainLoop() line 415~426):
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) {
if (task.period == 0) { // Non-repeating, remove
queue.removeMin();
task.state = TimerTask.EXECUTED;
} else { // Repeating task, reschedule
queue.rescheduleMin(
task.period<0 ? currentTime - task.period
: executionTime + task.period);
}
}
注:period就是TimeTask初始化時設定的執行間隔,taskFired是個boolean。
從這段代碼可以看出,TimerTask執行的條件是(executionTime<=currentTime)。其中executionTime取自TimerTask,而currentTime來自系統時間。原因就在于此,currentTime因為修改系統時間而提前了,所以這個條件(executionTime<=currentTime)永遠也不會達到,TimerTask將不會被執行。
避免方法:在修改系統時間后重新啟動應用:)