关于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将不会被执行。
避免方法:在修改系统时间后重新启动应用:)