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()
会导致此分辨率更改的示例。
上一篇: System.currentTimeMillis vs System.nanoTime
下一篇: R benchmarking of Spectre and Meltdown mitigations on Windows