關(guān)于Timer運(yùn)行時(shí)修改系統(tǒng)時(shí)間
對(duì)Sun JDK的Timer來說,系統(tǒng)時(shí)間修改到當(dāng)前時(shí)間之后,不會(huì)影響Timer的執(zhí)行;但是如果系統(tǒng)時(shí)間修改到當(dāng)前時(shí)間之前,就會(huì)導(dǎo)致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初始化時(shí)設(shè)定的執(zhí)行間隔,taskFired是個(gè)boolean。
從這段代碼可以看出,TimerTask執(zhí)行的條件是(executionTime<=currentTime)。其中executionTime取自TimerTask,而currentTime來自系統(tǒng)時(shí)間。原因就在于此,currentTime因?yàn)樾薷南到y(tǒng)時(shí)間而提前了,所以這個(gè)條件(executionTime<=currentTime)永遠(yuǎn)也不會(huì)達(dá)到,TimerTask將不會(huì)被執(zhí)行。
避免方法:在修改系統(tǒng)時(shí)間后重新啟動(dòng)應(yīng)用:)