这个答案是在 2011 年写的,从当时在操作系统上运行的 Sun JDK 实际做了什么的角度来看。那是很久以前的事!leventov 的回答提供了一个更新的视角。
那个帖子是错误的,并且nanoTime
是安全的。这篇文章有一条评论链接到Sun 的实时并发专家David Holmes 的博客文章。它说:
System.nanoTime() 是使用 QueryPerformanceCounter/QueryPerformanceFrequency API 实现的 [...] QPC 使用的默认机制由硬件抽象层 (HAL) 确定 [...] 此默认值不仅会跨硬件更改,还会跨操作系统更改版本。例如,Windows XP Service Pack 2 改变了使用电源管理计时器 (PMTimer) 而不是处理器时间戳计数器 (TSC) 的问题,因为 TSC 在 SMP 系统中的不同处理器上不同步,并且由于其频率的事实可以根据电源管理设置而变化(因此它与经过时间的关系)。
因此,在 Windows 上,在 WinXP SP2 之前这是一个问题,但现在不是了。
我找不到关于其他平台的第二部分(或更多),但那篇文章确实包含了 Linux 遇到并以相同方式解决相同问题的评论,并提供了指向clock_gettime(CLOCK_REALTIME) 的常见问题解答的链接,其中说:
- 所有处理器/内核的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 和摩托罗拉,与英特尔不同,实际上知道如何设计微处理器)。
遗憾的是,没有提到 SPARC 或 Solaris。当然,我们不知道 IBM JVM 做了什么。但是现代 Windows 和 Linux 上的 Sun JVM 做到了这一点。
编辑:这个答案基于它引用的来源。但我仍然担心它实际上可能是完全错误的。一些更新的信息将非常有价值。我刚刚看到一篇关于 Linux 时钟的四年新文章的链接,这可能很有用。