【发布时间】:2017-10-11 21:52:50
【问题描述】:
我正在编写的软件需要微秒级或更高分辨率的时间戳。
我打算将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 的文档说:
此方法提供纳秒级精度,但不一定 纳秒分辨率(即值更改的频率) - 否 除了决议至少与
currentTimeMillis()的那个。
所以它没有给我们提供比毫秒更好的分辨率保证。
在nanoTime(可以预见的是本机方法)的引擎盖下再深入一点:
Windows 使用
QueryPerformanceCounterAPI,它承诺 小于 1 微秒的分辨率非常棒。Linux 使用带有标志的
clock_gettime来确保该值是 单调但不承诺分辨率。Solaris 与 Linux 类似
消息来源没有提到 OSX 或基于 Unix 的操作系统如何处理这个问题。
(source)
我已经看到了一些模糊的暗示,即它“通常”具有微秒级分辨率,例如 this answer 在另一个问题上:
在大多数系统上,三个最低有效数字始终是 零。这实际上给出了微秒精度,但在 固定精度为一纳秒。
但没有来源,而且“通常”这个词非常主观。
问题:在什么情况下nanoTime会返回一个分辨率低于微秒的值?例如,可能主要操作系统版本不支持它,或者需要可能不存在的特定硬件功能。如果可以,请尽量提供来源。
我正在使用 Java 1.6,但如果对这个问题有实质性的好处,我可以升级的可能性很小。
【问题讨论】:
-
我很好奇你的用例是什么。显然,您不能期望时钟在设备之间如此紧密地同步。如果您从硬件录制某些内容,那么您将受到中断率的限制。
-
@user695022 金融立法规定,我们的时间戳必须是用于审计目的和其他东西的粒度。它们目前以毫秒为单位。
-
对负数检查要小心,它看起来很正常,但可能存在时钟不平衡导致负数。示例见stackoverflow.com/questions/7866206/…
-
您已经找到了它委托给哪些特定于平台的方法。您必须调查这些特定于平台的方法的行为。 linux 的
clock_gettime行为因硬件提供的不同而有很大差异。最终,由于平台和硬件特定的行为,规范被故意留下模糊不清。