我正在计划使用System.currentTimeMillis
与System.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的文档说:
This method provides nanosecond precision,but not necessarily
nanosecond resolution (that is,how frequently the value changes) – no
guarantees are made except that the resolution is at least as good as
that ofcurrentTimeMillis()
.
所以没有给我们一个比毫秒更好的解决方案的保证.
进一步深入,在nanoTime的引擎下(这可以预见为本机的方法):
> Windows使用允诺的QueryPerformanceCounter
API
分辨率小于1微秒,这是伟大的.
> Linux使用带有标志的clock_gettime
来确保其值
单调但对决议没有承诺.
Solaris类似于Linux
源码并没有提到OSX或基于Unix的操作系统是如何处理的.
(source)
我已经看到了一些模糊的暗示,它将“通常”具有微秒级决议,例如this answer另一个问题:
On most systems the three least-significant digits will always be
zero. This in effect gives microsecond accuracy,but reports it at the
fixed precision level of a nanosecond.
但没有来源,“通常”这个词是非常主观的.
问题:在什么情况下,nanoTime会返回分辨率比微秒差的值?例如,也许主要的操作系统版本不支持它,或者需要特定的硬件功能,这可能不存在.请尝试提供资料,如果可以的话.
我正在使用Java 1.6,但是如果对这个问题有很大的好处,那么我可以升级的机会很小.
解决方法
Question: Under what circumstances might nanoTime return a value whose resolution is worse than microseconds? What operating systems,hardware,JVMs etc. that are somewhat commonly used might this affect? Please try to provide sources if you can.
要求列出所有可能遭受该约束的情况的列表似乎有点多,没有人知道您的软件将在哪个环境下运行.但是为了证明这可能发生,可以看到这个blog post by aleksey shipilev,在那里他描述了一个案例,其中纳米时间变得不太准确(在自己的延迟方面)比Windows机器上的微秒,由于争用.
另一种情况是在虚拟机下运行的软件以非常粗略的方式仿真硬件时钟.
由于平台和硬件特定的行为,该规范已经被故意地模糊了.