currentTimeMillis()并在nanoTime()

时间:2015-12-04 14:45:26

标签: java windows windows-7

更重要的更新:我在Java 8上尝试了相同的代码,System.currentTimeMillis()按预期工作:

1449242048.588 368936.080131
1449242048.590 368936.082132
1449242048.592 368936.084132
1449242048.594 368936.086132
1449242048.596 368936.088133
1449242048.598 368936.090133
1449242048.600 368936.092133
1449242048.602 368936.094133
1449242048.604 368936.096133
1449242048.606 368936.098134
1449242048.608 368936.100134
1449242048.610 368936.102134
Main run took 20.036 seconds. Expected time: 20.0

感谢@Tunaki提示。

更新:我认为引用此处重复问题的回复中引用的link非常有用:

  

System.currentTimeMillis()是使用。实现的   GetSystemTimeAsFileTime方法,它基本上只读取低   Windows维护的解析时间值。读这个   全局变量自然很快 - 大约6个周期   报道的信息。此时间值以常量更新   无论定时器中断如何编程,速率 -   根据平台,这将是10毫秒或 15毫秒(此值   似乎与默认的中断周期有关。)

(强调我的)

我记录的一些数据的时间戳来自System.nanoTime()。当我回放它时,我使用一个在紧密循环中旋转的线程,调用System.nanoTime()直到经过足够的纳秒来复制时间戳之间的差异。

我注意到将System.currentTimeMillis()与这种播放混合会产生非常奇怪的结果,至少在Windows 7上。纳米时间按预期更新,但毫秒时间一次跳跃16毫秒。 / p>

整体等待时间(用millis测量)仍然如预期。这是我写的小程序日志的尾端,用来说明这一点:

1449238154.610 365042.452692
1449238154.626 365042.454692
1449238154.626 365042.456692
1449238154.626 365042.458692
1449238154.626 365042.460692
1449238154.626 365042.462693
1449238154.626 365042.464693
1449238154.626 365042.466693
1449238154.626 365042.468693
1449238154.642 365042.470693
1449238154.642 365042.472694
1449238154.642 365042.474694
1449238154.642 365042.476694
1449238154.642 365042.478694
1449238154.642 365042.480694
Main run took 20.0 seconds. Expected time: 20.0

左边是毫秒时间,右边是纳米时间,均标准化为秒。如您所见,毫秒时间不是每毫秒更新一次,而是每16毫秒更新一次。

有人能解释一下发生了什么吗?

我附上了我为测试此效果而编写的代码。环境是Windows 7企业版,Java 7,8个内核,2个CPU。

public class NanotimeTest {

    private static final long DELAY_NANOS = 2_000_000;
    private static final int ITERATIONS = 10_000;

    private static class Times {
        public long millis;
        public long nanos;
    }

    Times[] times = new Times[ITERATIONS];

    public static void main(String[] args) {
        new NanotimeTest().run();
    }

    private void run() {
        for (int i = 0; i < ITERATIONS; i++) {
            times[i] = new Times();
        }


        System.out.println("Starting warmup");
        produceTimes(1000);

        System.out.println("Starting main run");
        long start = System.currentTimeMillis();
        produceTimes(DELAY_NANOS);
        long end = System.currentTimeMillis();


        for(Times t : times) {
            System.out.printf("%.3f %f\n", t.millis / 1000.0, t.nanos / 1_000_000_000.0);
        }

        System.out.println("Main run took " + (end - start)/1000.0 + " seconds. Expected time: " + (DELAY_NANOS * ITERATIONS)/1_000_000_000.0); 
    }

    private void produceTimes(long delayNanos) {
        for (int i = 0; i < ITERATIONS; i++) {

            long start;

            times[i].millis = System.currentTimeMillis();
            times[i].nanos = start = System.nanoTime();

            while (System.nanoTime() - start < delayNanos) {
                // go on
            }
        }
    }

}

0 个答案:

没有答案