System.currentTimeMillis与System.nanoTime

精度与Vs. 精确

我想知道的是在我的游戏中更新我的对象位置时,我应该使用System.currentTimeMillis()还是System.nanoTime() ? 他们的运动变化与自上次调用以来的时间成正比,我希望尽可能精确。

我已经读过,不同操作系统之间存在一些严重的时间分辨率问题(即Mac / Linux具有近1ms的分辨率,而Windows具有50ms的分辨率?)。 我主要在Windows上运行我的应用程序,并且50毫秒的分辨率看起来相当不准确。

有没有比我列出的两个更好的选择?

任何建议/意见?


如果您只是在寻找非常精确的测量时间 ,请使用System.nanoTime()System.currentTimeMillis()将为您提供自时代以来最准确的可能流逝时间(以毫秒为单位System.nanoTime() ,但System.nanoTime()会为您提供相对于某个任意点的精确时间为纳秒的时间。

从Java文档:

public static long nanoTime()

以毫微秒为单位返回最精确的可用系统计时器的当前值。

此方法只能用于测量已用时间,并且与系统或挂钟时间的任何其他概念无关。 返回的值表示自某些固定但随意​​的时间以来的纳秒(可能在将来,因此值可能为负)。 该方法提供了纳秒精度,但不一定是纳秒精度。 没有保证值的变化频率。 由于数值溢出,连续调用中跨度大于约292年(263纳秒)的差异将无法准确计算经过时间。

例如,要测量某些代码需要执行多长时间:

long startTime = System.nanoTime();    
// ... the code being measured ...    
long estimatedTime = System.nanoTime() - startTime;

另请参阅:JavaDoc System.nanoTime()和JavaDoc System.currentTimeMillis()以获取更多信息。


线程安全

由于没有人提到过这个...

不安全

比较不同线程之间System.nanoTime()调用的结果是不安全的。 即使线程的事件以可预测的顺序发生,纳秒的差异可能是正面的或负面的。

安全

System.currentTimeMillis()在线程间使用是安全的。


Arkadiy更新:在Oracle Java 8中,我观察到Windows 7上System.currentTimeMillis()更正确行为。时间以1毫秒的精度返回。 OpenJDK中的源代码没有改变,所以我不知道是什么导致了更好的行为。


Sun的David Holmes几年前发布了一篇博客文章,详细介绍了Java时序API(特别是System.currentTimeMillis()System.nanoTime() ),当您想要使用它时,以及它们如何使用在内部工作。

在热点虚拟机内部:时钟,定时器和调度事件 - 第一部分 - Windows

Java在Windows上用于具有定时等待参数的API的定时器的一个非常有趣的方面是定时器的分辨率可以根据其他API调用可能发生的变化而改变 - 系统范围(不仅在特定过程中) 。 他显示了一个使用Thread.sleep()会导致此分辨率更改的示例。

链接地址: http://www.djcxy.com/p/86533.html

上一篇: System.currentTimeMillis vs System.nanoTime

下一篇: R benchmarking of Spectre and Meltdown mitigations on Windows