关于Timer
和ScheduledThreadPoolExecutor
之间差异的highly voted answer on SO,在列举差异时会提到以下内容:
定时器可能对系统时钟的变化很敏感, ScheduledThreadPoolExecutor不是。
以上是在Java Concurrency in Practice这本伟大的书中逐字提到的。
除了上面提到的那个,我理解答案中提到的要点。说Timers
对系统时钟敏感而ScheduledThreadPoolExecutors
不是这样的,这是什么意思?
答案 0 :(得分:9)
Timer
使用System.currentTimeMillis()
代表挂钟时间,绝不应该用于检查相对时间,例如确定运行时间长度,或者在这种情况下,在执行任务之前要延迟多长时间。 System.currentTimeMillis()
会受到自动调整系统时钟或甚至手动更改系统时钟等因素的影响。因此,如果你打电话两次并检查你得到的时间之间的差异,你甚至可以得到一个负数。
System.nanoTime()
专门用于测量经过时间,应该用于此类事情。
答案 1 :(得分:5)
Timer
使用System.currentTimeMillis()
来确定下一次执行任务。
但ScheduledThreadPoolExecutor
使用System.nanoTime()
。
同样nanoTime()
方法只能用于衡量已用时间,与系统或挂钟时间的任何其他概念无关。
System.currentTimeMillis()
敏感到系统时钟
System.nanoTime()
对系统时钟不敏感,因为它会测量经过的时间。
Java文档:System.nanoTime()
此方法只能用于测量经过的时间而不是 与系统或挂钟时间的任何其他概念有关。价值 返回表示自固定但任意时间以来的纳秒 (也许在将来,所以价值可能是负面的。)
答案 2 :(得分:1)
查看源代码,Timer
类使用System.currentTimeMillis()
计划任务。 ScheduledThreadPoolExecutor
使用System.nanoTime()
。
currentTimeMillis()
将倾向于使用OS时钟,即追踪当前日期/时间的时钟。 nanoTime()
将倾向于使用更高分辨率的硬件时钟。
如果您将操作系统时钟移回一小时,那么currentTimeMillis()
可能会反映nanoTime()
不应该。{/ p>