准确Vs.精确

我想知道的是,我是否应该使用系统。currenttimemillis()或系统。nanotime()时更新我的对象的位置在我的游戏?它们移动的变化与上次通话后经过的时间成正比,我希望尽可能精确。

我读到过不同操作系统之间有一些严重的时间分辨率问题(即Mac / Linux的分辨率几乎是1毫秒,而Windows的分辨率是50毫秒??)我主要在windows上运行我的应用程序,50ms的分辨率似乎非常不准确。

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

有什么建议/意见吗?


当前回答

system. currenttimemillis()对于运行时间来说是不安全的,因为这个方法对系统的实时时钟变化很敏感。 您应该使用System.nanoTime。 请参阅Java系统帮助:

关于nanoTime方法:

. .这种方法提供纳秒精度,但不一定 纳秒分辨率(即值变化的频率)—不 除了保证分辨率至少和 currentTimeMillis()..

如果你使用System.currentTimeMillis(),你的运行时间可以是负数(返回<-到未来)

其他回答

既然没人提过这一点……

在不同的JVM之间比较System.nanoTime()调用的结果是不安全的,每个JVM可能有一个独立的“起始”时间。

system . currenttimemillis()将在jvm之间返回(近似)相同的值,因为它与系统墙壁时钟时间绑定。

如果你想计算两个事件之间经过的时间,就像秒表一样,使用nanoTime();系统时钟的改变使得currentTimeMillis()在这个用例中不正确。

旧的jvm中不支持System.nanoTime()。如果这是一个问题,请坚持使用currentTimeMillis

关于准确性,你几乎是正确的。在一些Windows机器上,currentTimeMillis()的分辨率约为10ms(而不是50ms)。我不知道为什么,但是一些Windows机器和Linux机器一样准确。

我过去使用过GAGETimer,取得了一定的成功。

这里的一个问题是nanoTime方法的不一致性。对于相同的输入,它不会给出非常一致的值。currentTimeMillis在性能和一致性方面做得更好,而且,尽管没有nanoTime那么精确,但它的误差范围更低,因此它的值更准确。因此,我建议您使用currentTimeMillis

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


Sun的David Holmes在几年前发表了一篇博客文章,其中非常详细地介绍了Java计时api(特别是System.currentTimeMillis()和System.nanoTime()),以及您希望在何时使用它们,以及它们在内部是如何工作的。

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

Java在Windows上为具有定时等待参数的API使用的计时器的一个非常有趣的方面是,计时器的分辨率可以根据可能已经进行的其他API调用而改变-系统范围(不仅仅是在特定进程中)。他展示了一个使用Thread.sleep()会导致分辨率改变的例子。

system. currenttimemillis()对于运行时间来说是不安全的,因为这个方法对系统的实时时钟变化很敏感。 您应该使用System.nanoTime。 请参阅Java系统帮助:

关于nanoTime方法:

. .这种方法提供纳秒精度,但不一定 纳秒分辨率(即值变化的频率)—不 除了保证分辨率至少和 currentTimeMillis()..

如果你使用System.currentTimeMillis(),你的运行时间可以是负数(返回<-到未来)