这篇答案是在2011年从Sun JDK的角度出发,介绍当时操作系统上运行的情况。那已经是很久以前的事情了!leventov's 答案提供了更为实时的视角。
那篇帖子是错误的,nanoTime
是安全的。该帖子中有一条评论链接到David Holmes的博客文章,他是Sun公司的实时和并发专家。该文章说:
System.nanoTime()是使用QueryPerformanceCounter/QueryPerformanceFrequency API实现的。[...] QPC使用的默认机制由硬件抽象层(HAL)确定。[...] 这个默认值不仅在硬件之间而且还在操作系统版本之间改变。例如,Windows XP Service Pack 2由于TSC在SMP系统中没有被同步在不同处理器上,并且其频率可以基于电源管理设置而变化(因此与经过的时间的关系也会发生变化),因此更改了默认值,使用电源管理计时器(PMTimer)。
因此,在Windows上,这个问题直到WinXP SP2之前都是一个问题,但现在不是了。
我找不到其他平台的第二部分(或更多内容),但是该文章确实包含一条备注,Linux已经遇到并以同样的方式解决了相同的问题,并链接到了clock_gettime(CLOCK_REALTIME)的 FAQ,其中写道:
- clock_gettime(CLOCK_REALTIME)是否在所有处理器/核心上保持一致?(是否与体系结构有关?例如ppc、arm、x86、amd64、sparc等)。
它应该保持一致,否则会被视为有缺陷。
然而,在x86 / x86_64上,可能会出现未同步或变频TSC导致时间不一致的情况。 2.4内核在这方面没有保护措施,早期的2.6内核也做得不太好。从2.6.18开始,检测此问题的逻辑更好,并且通常会回退到安全的时钟源。
ppc始终具有同步的时间基准,因此不应该是一个问题。
因此,如果Holmes的链接可以被解释为意味着nanoTime
调用clock_gettime(CLOCK_REALTIME)
,则在x86上的内核2.6.18及更高版本以及PowerPC上始终安全(因为IBM和Motorola知道如何设计微处理器,而Intel不知道)。
遗憾的是,没有提到SPARC或Solaris。当然,我们不知道IBM JVM会怎么做。但是,现代Windows和Linux上的Sun JVM可以正确处理这个问题。
编辑:此答案基于其引用的来源。但我仍然担心它可能完全错误。一些更加最新的信息将非常有价值。我刚刚遇到了一个关于Linux时钟的四年新的文章,可能会有用。