java,Timer,TimerTask,计时器,计时时间不准确,总有很大的误差。求教
用TimerTask实现了一个计时器,每日固定时间执行一些操作,在本地的机器测试通过都没有问题,可是把代码放至服务器上的时候,计时器会出现执行操作时间不准的问题,比如:我的任务是需要下午18点执行,最后检查出执行时间为18点26.
注意几点:
1.本地测试完全没有问题,都是准时执行,分毫不差。本地与服务器代码区别是外网代码是经过加密混淆的。有可能是这个问题么?
2.是否是云服务器的问题呢? 已经检查过服务器的系统时间时区的设置,已经确认无误。
3.并且计时器的误差会随着任务运行的时间越长,误差越大。比如:设定每日18:00执行,昨日执行操作的时间为18:26,今日执行操作的时间为19:16. 可执行操作的周期为24小时呀,是一个不变的值,排除这种错误。
请问大侠们遇到过这种问题么?求指教,万分感谢。
Answers
java里timer确实不能保证实时, "此类不 提供实时保证:它使用 Object.wait(long) 方法来安排任务。". 但你这里一天差半小时, 明显应该不是这个问题.
如果排除是 服务器时间设定的问题, 那么可能的原因:
每一个Timer对应一个后台线程, 此线程顺序执行 在Timer上schedule的TimerTask; 如果某一个Task耗时很长, 那么就会延迟 下一个Task的执行.
见 @JavaEE中用timer模拟session的过期销毁,如何保证不出现大量的无用线程,以减轻服务器的承载?
希望对你有所帮助.
PS:
刚过了遍源码, 你用的是schedule方法, 不是scheduleAtFixedRate吧?
如果是scheduleAtFixedRate, 即使你此次执行延期了, timer会保证此延期不会叠加到下一次; schedule则会叠加, 和你的现象比较复合.
你可以去看一下Timer -> TaskQueue -> mainLoop():
} else { // Repeating task, reschedule
queue.rescheduleMin(
task.period<0 ? currentTime - task.period
: executionTime + task.period);
在Timer的schedule和scheduleAtFixedRate里, 可以看到scheduleAtFixedRate保证period为正整数, schedule保证period为负整数.