什么是我可以从System.nanoTime合理期望的最差分辨率?

时间:2017-05-12 14:21:08

标签: java linux windows time

我正在编写需要时间戳的软件,以微秒级或更好的分辨率。

我计划将System.currentTimeMillisSystem.nanoTime结合使用,但这只是一个粗略的代码草图:

private static final long absoluteTime = (System.currentTimeMillis() * 1000 * 1000);
private static final long relativeTime = System.nanoTime();

public long getTime()
{
    final long delta = System.nanoTime() - relativeTime;
    if (delta < 0) throw new IllegalStateException("time delta is negative");
    return absoluteTime  + delta;
}

nanoTime的文档说:

  

此方法提供纳秒精度,但不一定   纳秒分辨率(即,值的变化频率) - 否   除了分辨率至少与分辨率一样好之外,还要做出保证   那是currentTimeMillis()

所以它没有给我们一个比毫秒更好的分辨率保证。

更深入一点,在nanoTime的引擎盖下(可以预见的是一种原生方法):

  • Windows使用承诺a的QueryPerformanceCounter API 分辨率小于1微秒,这很棒。

  • Linux使用带有标志的clock_gettime来确保值 单调,但对决议没有任何承诺。

  • Solaris类似于Linux

  • 来源并未提及OSX或基于Unix的操作系统如何处理此问题。

source

我已经看到了一些含糊不清的暗示,它会&#34; 通常&#34;有微秒分辨率,例如this answer在另一个问题上:

  

在大多数系统中,三个最低有效数字始终为   零。这实际上提供了微秒的准确性,但报告了它   固定精度水平为纳秒。

但是没有来源和单词&#34;通常&#34;是非常主观的。

问题:在什么情况下nanoTime可能会返回分辨率低于微秒的值?例如,可能主要的操作系统版本不支持它,或者需要可能不存在的特定硬件功能。如果可以,请尝试提供来源。

我使用的是Java 1.6,但如果在这个问题上有很多好处的话,我很有可能升级。

1 个答案:

答案 0 :(得分:7)

  

问题:在什么情况下nanoTime会返回分辨率低于微秒的值?某些常用的操作系统,硬件,JVM等可能会影响到什么?如果可以,请尝试提供来源。

要求详细列出所有可能违反该约束条件的情况,似乎有点多,没有人知道您的软件将在哪些环境下运行。但为了证明它可能发生,请参阅此blog post by aleksey shipilev,其中他描述了一个案例,由于争用,纳米级变得不那么准确(就其自身的延迟而言)而不是Windows机器上的微秒。

另一种情况是在虚拟机下运行的软件以非常粗略的方式模拟硬件时钟。

由于平台和硬件特定的行为,规范已被故意模糊不清。

一旦您确认您正在使用的硬件和操作系统确实提供了您所需要的并且VM通过了必要的功能,您就可以“合理地期望”微秒精度。