26 December 2019

java中获取时间常用两种方法System.currentTimeMillisSystem.nanoTime。文档中,对这两个方法的使用场景做了明确指定。

  • System.currentTimeMilllis: 可以作为墙上时间使用,精度取决于底层操作系统,可能会达到数十毫秒。
  • System.nanoTime: 不可用做墙上时间,只能用来测量时间流逝。提供了纳秒的准度,精度则未必。

从描述上看,做性能测试的话,还是用System.nanoTime方法更好些。

从实现上看,linux为例,System.currentTimeMilllis的值直接取自于函数gettimeofday的值。虽然gettimeofday可以得到微秒的准度,但经过换算后,只能达到毫秒的准度了,符合System.currentTimeMilllis方法文档的描述。此外,若是手动修改的系统时间,则函数gettimeofday会返回过去的值,连带System.currentTimeMilllis方法也会如此。

另一方面,System.nanoTime的利用高精度计时器来计算(-lrtlibrt.so.1)时间流逝,准度可达纳秒,基于 monotonic clock的特性,即便手动修改时间,函数也不会返回过去的值,同时这个特性注定了,该函数只能用来测量时间流逝,不能用来表示墙上时间。当然,如果系统不支持 monotonic clock,还是会通过gettimeofday返回数值,此时准度退化为毫秒。