【问题标题】:Getting precise elapsed time using Java to the Millisecond使用 Java 获得精确到毫秒的经过时间
【发布时间】:2011-03-29 17:07:53
【问题描述】:

我一直在寻找我的困境的答案,并找到了一些有用的提示,但没有解决我的具体问题,所以我希望这里的人可以帮助我。

我试图在 Java 中获得精确到毫秒的经过时间。我正在使用 System.nanoTime() 来获取当前时间并在以下代码中实现它。请注意,这是我用来测试其精度的代码。

long startTime = System.nanoTime()/1000000;
而(真)
{
System.out.println((System.nanoTime()/1000000)-startTime);
}

部分输出如下所示。

1110
1112
1112
1113
1114
1118
第1120章

第一个数字是秒数,第二个,十分之一秒,第三个,百分之一,最后一个是千分之一。你在这里看不到它,但我精确到百分之一 - 没有跳过或重复的数字。然而,千分之一远非精确。 0 -> 2 -> 2 -> 3 -> 4 -> 8 -> 0。对于我正在做的事情,我需要精确到千分之一,从我读过的所有内容来看,似乎 System.nanoTime() 应该是能够提供毫秒级的精度。

我做错了什么还是有其他方法可以精确到毫秒?

【问题讨论】:

标签: java time elapsed


【解决方案1】:

这里有两个因素。

首先,即使System.nanoTime() 也不一定非常精确 - 它只是使用可用的最佳时钟(并且不跟随时钟变化,因此它永远不会后退或前进)。

其次,您的 Java 程序并不是您计算机上运行的唯一程序 - 因此您的代码(本质上是调用本机 nanoTime 函数和结果的输出)每次都会花费不同的时间。例如,一个输出可能需要超过一整毫秒,而另一个输出只需要一半或更少。

尝试输出更多的数字(即除以较小的数字),结果将有助于理解。

【讨论】:

    【解决方案2】:

    减法后除以 100 万,并使用 long 文字。

    long startTime = System.nanoTime();
    
    while (true)
    {
        System.out.println((System.nanoTime() - startTime)/1000000L);
    }
    

    演示(更新):http://ideone.com/X5RRa

    【讨论】:

    • 这不会改变循环不能保证定期执行的事实,这似乎是他所期望的。
    • 我想我所期待的是毫秒数会定期增加(0、1、2、3 等)。十分之一和百分之一都可以。你是说毫秒内不会出现这种情况?
    • @Antillies:您希望循环每毫秒运行一次?为什么?
    • @Matt:我想我的印象是循环执行得很快。但我想我已经意识到你们所说的循环执行所花费的时间正在创造我认为不精确的东西。我对您的理解是否正确,这不是不精确,而是由于循环执行需要时间,循环无法尽快打印出毫秒数?
    • 感谢大家的帮助。我想我对现在必须做什么有了更好的了解。
    【解决方案3】:

    java.time

    旧的日期时间类现在被 java.time 类取代。

    java.time 类支持高达nanoseconds 的分辨率。但请记住,实际分辨率和精度取决于主机的硬件时钟。所以您的结果有所不同。

    Instant instant = Instant.now();  
    

    2016-01-02T12:34:56.123456789Z

    要将可能的nanosecond 分辨率降低到milliseconds,请调用Instant::truncatedTo 方法。

    Instant instantTruncated = Instant.now().trucatedTo( ChronoUnit.MILLIS );
    

    2016-01-02T12:34:56.123Z

    请记住,大多数计算机硬件时钟在毫秒-微秒-纳秒的粒度上不是很准确


    小提示:虽然 java.time 类支持存储纳秒分辨率,但在 Java 8 中,Clock 的旧版实现仅限于捕获当前时刻毫秒而不是纳秒。 Java 9 带来了 fresh implementationClock,因此可以根据您的主机计算机时钟硬件和主机操作系统的能力以高达纳秒的分辨率捕获当前时刻。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 2016-06-22
      • 1970-01-01
      • 2021-04-08
      相关资源
      最近更新 更多