Windows XP上的System.nanoTime()

时间:2011-10-22 11:05:54

标签: java time

我刚刚在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()好多了。但为什么?我们能相信这个结果吗?

3 个答案:

答案 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_clockshttp://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html

编辑 - 根据评论:

当调用nanoTime时,JVM本身在内部使用上述函数,这与JNI完全无关 - 它们不会暴露给Java代码!

编辑2 - 根据评论:

nanoTime()是准确衡量已用时间的正确工具,而currentTimeMillis是处理绝对时间的正确工具。

答案 2 :(得分:0)

了解方法的最佳方法是阅读its javadoc。不要猜测它使用实验做了什么。

  

返回最精确的可用系统计时器的当前值,   以纳秒为单位。

     

此方法只能用于测量经过的时间而不是   与系统或挂钟时间的任何其他概念有关。价值   返回表示自固定但任意时间以来的纳秒   (也许在未来,所以价值观可能是负面的)。这种方法   提供纳秒级精度,但不一定是纳秒级   准确性。不保证值的变化频率。