如果您只是想要精确测量经过的时间,请使用System.nanoTime()
.System.currentTimeMillis()
将为您提供自纪元以来最精确的可能的经过时间(以毫秒为单位),但System.nanoTime()
相对于某个任意点,您可以获得纳秒精确的时间.
从Java文档:
public static long nanoTime()返回最精确的可用系统计时器的当前值,以纳秒为单位.
此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关.返回的值表示纳秒,因为某些固定但是任意时间(可能在将来,因此值可能为负).该方法提供纳秒精度,但不一定是纳秒精度.不保证值的变化频率. 由于数值溢出,跨越大于约292年(2 63纳秒)的连续调用的差异将无法准确计算经过的时间.
例如,要测量某些代码执行所需的时间:
long startTime = System.nanoTime(); // ... the code being measured ... long estimatedTime = System.nanoTime() - startTime;
另请参阅:JavaDoc System.nanoTime()和JavaDoc System.currentTimeMillis()以获取更多信息.
如果您只是想要精确测量经过的时间,请使用System.nanoTime()
.System.currentTimeMillis()
将为您提供自纪元以来最精确的可能的经过时间(以毫秒为单位),但System.nanoTime()
相对于某个任意点,您可以获得纳秒精确的时间.
从Java文档:
public static long nanoTime()返回最精确的可用系统计时器的当前值,以纳秒为单位.
此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关.返回的值表示纳秒,因为某些固定但是任意时间(可能在将来,因此值可能为负).该方法提供纳秒精度,但不一定是纳秒精度.不保证值的变化频率. 由于数值溢出,跨越大于约292年(2 63纳秒)的连续调用的差异将无法准确计算经过的时间.
例如,要测量某些代码执行所需的时间:
long startTime = System.nanoTime(); // ... the code being measured ... long estimatedTime = System.nanoTime() - startTime;
另请参阅:JavaDoc System.nanoTime()和JavaDoc System.currentTimeMillis()以获取更多信息.
既然没有人提到过这个......
比较System.nanoTime()
不同线程之间的调用结果是不安全的.即使线程的事件以可预测的顺序发生,纳秒的差异也可以是正的或负的.
System.currentTimeMillis()
在线程之间使用是安全的.
Arkadiy更新:我System.currentTimeMillis()
在Oracle Java 8中观察到Windows 7上更正确的行为.返回的时间精度为1毫秒.OpenJDK中的源代码没有改变,所以我不知道是什么原因造成了更好的行为.
孙大卫霍姆斯发布了博客文章一对夫妇多年前拥有的Java API的时机非常详细的外观(尤其是System.currentTimeMillis()
和System.nanoTime()
),当你想使用的,以及它们如何在内部工作.
Hotspot VM内部:时钟,定时器和调度事件 - 第一部分 - Windows
对于具有定时等待参数的API,Java在Windows上使用的计时器的一个非常有趣的方面是,计时器的分辨率可以根据可能已经进行的其他API调用而改变 - 系统范围(不仅仅在特定进程中) .他展示了一个使用Thread.sleep()
将导致此分辨率更改的示例.
System.nanoTime()
旧JVM不支持.如果这是一个问题,坚持下去currentTimeMillis
关于准确性,你几乎是正确的.在某些Windows机器上,currentTimeMillis()
分辨率约为10毫秒(不是50毫秒).我不确定为什么,但有些Windows机器和Linux机器一样准确.
我过去使用GAGETimer取得了一定的成功.
正如其他人所说,currentTimeMillis是时钟时间,由于夏令时,用户更改时间设置,闰秒和互联网时间同步而改变.如果您的应用依赖于单调增加的经过时间值,您可能更喜欢nanoTime.
你可能会认为玩家不会在游戏过程中摆弄时间设置,也许你是对的.但是,不要低估因互联网时间同步或远程桌面用户造成的中断.nanoTime API不受这种破坏的影响.
如果您想使用时钟时间,但避免因互联网时间同步导致的不连续性,您可能会考虑使用诸如Meinberg之类的NTP客户端,它将时钟频率"调整"为零,而不是仅定期重置时钟.
我是根据个人经验说的.在我开发的天气应用中,我随机发生风速峰值.我花了一段时间才意识到我的时基被典型PC上的时钟时间行为所扰乱.当我开始使用nanoTime时,我的所有问题都消失了.对于我的应用,一致性(单调性)比原始精度或绝对精度更重要.
是的,如果需要使用这种精度System.nanoTime()
,但要注意您需要Java 5+ JVM.
在我的XP系统上,我看到使用以下代码报告的系统时间至少为100微秒 278 纳秒:
private void test() { System.out.println("currentTimeMillis: "+System.currentTimeMillis()); System.out.println("nanoTime : "+System.nanoTime()); System.out.println(); testNano(false); // to sync with currentTimeMillis() timer tick for(int xa=0; xa<10; xa++) { testNano(true); } } private void testNano(boolean shw) { long strMS=System.currentTimeMillis(); long strNS=System.nanoTime(); long curMS; while((curMS=System.currentTimeMillis()) == strMS) { if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)); } } if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)+", Milli: "+(curMS-strMS)); } }