我刚刚在Windows XP上找到System.currentTimeMillis is not accurate,现在我尝试使用相同的代码System.nanoTime()
。
自1ms = 1,000,000ns
以来,我认为结果应为15,000,000ns
,但事实并非如此。
参见示例代码:
public class NanoTime {
public static void main(String[] args) {
long start = 0;
long end = 0;
while (true) {
if (start == 0) {
start = System.nanoTime();
} else {
long current = System.nanoTime();
if (current != start) {
end = current;
break;
}
}
}
System.out.println("The time interval of your OS: " + (end - start) + "ns");
}
}
结果是:
The time interval of your OS: 655ns
似乎它比System.currentTimeMillis()
好多了。但为什么?我们能相信这个结果吗?
答案 0 :(得分:4)
为什么?
因为它不是以同样的方式准确。
来自Javadocs:
此方法只能用于测量经过时间,与系统或挂钟时间的任何其他概念无关。
所以是的,它可以准确地测量经过的时间。给你一个绝对的时间是不好的,你不会比System.currentTimeMillis()
更准确,至少没有明确地与NTP协调等。使用正确的工具来完成工作,而不是设计一个系统这需要非常准确的绝对时间。
答案 1 :(得分:4)
如果您的Windows XP有SP3,那么您可以相信结果......在Windows上,JVM使用基本位于HAL的nanoTime()
API实现QueryPerformanceCounter/QueryPerformanceFrequency
内部(硬件抽象层)并使用一些相当准确的CPU内部间隔指令......它只适用于间隔测量不适合时间处理......
有关详细说明,请参阅http://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks和http://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html
编辑 - 根据评论:
当调用nanoTime
时,JVM本身在内部使用上述函数,这与JNI完全无关 - 它们不会暴露给Java代码!
编辑2 - 根据评论:
nanoTime()
是准确衡量已用时间的正确工具,而currentTimeMillis
是处理绝对时间的正确工具。
答案 2 :(得分:0)
了解方法的最佳方法是阅读its javadoc。不要猜测它使用实验做了什么。
返回最精确的可用系统计时器的当前值, 以纳秒为单位。
此方法只能用于测量经过的时间而不是 与系统或挂钟时间的任何其他概念有关。价值 返回表示自固定但任意时间以来的纳秒 (也许在未来,所以价值观可能是负面的)。这种方法 提供纳秒级精度,但不一定是纳秒级 准确性。不保证值的变化频率。