System.nanoTime() 对比 System.currentTimeMills()

最近在看datax的源码,看到System.nanoTime() ,特地学习记录下;

1,上源码 (System类)

System.nanoTime()

    /**
     * Returns the current value of the running Java Virtual Machine's
     * high-resolution time source, in nanoseconds.
     *
     * <p>This method can only be used to measure elapsed time and is
     * not related to any other notion of system or wall-clock time.
     * The value returned represents nanoseconds since some fixed but
     * arbitrary <i>origin</i> time (perhaps in the future, so values
     * may be negative).  The same origin is used by all invocations of
     * this method in an instance of a Java virtual machine; other
     * virtual machine instances are likely to use a different origin.
     *
     * <p>This method provides nanosecond precision, but not necessarily
     * nanosecond resolution (that is, how frequently the value changes)
     * - no guarantees are made except that the resolution is at least as
     * good as that of {@link #currentTimeMillis()}.
     *
     * <p>Differences in successive calls that span greater than
     * approximately 292 years (2<sup>63</sup> nanoseconds) will not
     * correctly compute elapsed time due to numerical overflow.
     *
     * <p>The values returned by this method become meaningful only when
     * the difference between two such values, obtained within the same
     * instance of a Java virtual machine, is computed.
     *
     * <p> For example, to measure how long some code takes to execute:
     *  <pre> {@code
     * long startTime = System.nanoTime();
     * // ... the code being measured ...
     * long estimatedTime = System.nanoTime() - startTime;}</pre>
     *
     * <p>To compare two nanoTime values
     *  <pre> {@code
     * long t0 = System.nanoTime();
     * ...
     * long t1 = System.nanoTime();}</pre>
     *
     * one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
     * because of the possibility of numerical overflow.
     *
     * @return the current value of the running Java Virtual Machine's
     *         high-resolution time source, in nanoseconds
     * @since 1.5
     */
    public static native long nanoTime();

翻译下来如下:

返回正在运行的Java虚拟机的高分辨率时间源的当前值,以纳秒计。

该方法可能仅仅用于测量已经逝去的时间,并且与任何其它系统或者挂钟时间概念无关。该返回值表示从某个固定但任意的原点时间(可能在未来,所以值可能是负数)开始的纳秒数。在一个java虚拟机实例中,所有该方法的调用都使用相同的原点;其它虚拟机实例很可能使用不同的源头。

该方法提供了纳秒级别的精度,但是不一定是纳秒级分辨率(也就是该值改变的频率)———— 除非这个分辨率至少和currentTimeMillis()一样好,否则将不会做任何保证。

在跨越大于292年(2的63次方纳秒)左右的连续调用中,这个差值将不能正确地计算已经过去的时间,因为数字溢出。

仅仅只有当在同一java虚拟机实例中获取的两个值之间的差值被计算时,返回值才有意义。

例如,去测量某代码执行花费了多长时间:
 long startTime = System.nanoTime();
 //...被测量的代码...
 long estimatedTime = System.nanoTime() - startTime;

要比较两个nanoTime的值:
 long t0 = System.nanoTime();
 ...
 long t1 = System.nanoTime()。
因为数字溢出的可能性,您应该使用"t1 - t0 < 0",而不是"t1 < t0"(来判断它们的大小,笔者注)。
@return 当前正在运行的java虚拟机的高精度时间资源值,以纳秒为单位。
@since 1.5

System.currentTimeMillis()

    /**
     * Returns the current time in milliseconds.  Note that
     * while the unit of time of the return value is a millisecond,
     * the granularity of the value depends on the underlying
     * operating system and may be larger.  For example, many
     * operating systems measure time in units of tens of
     * milliseconds.
     *
     * <p> See the description of the class <code>Date</code> for
     * a discussion of slight discrepancies that may arise between
     * "computer time" and coordinated universal time (UTC).
     *
     * @return  the difference, measured in milliseconds, between
     *          the current time and midnight, January 1, 1970 UTC.
     * @see     java.util.Date
     */
    public static native long currentTimeMillis();

翻译
*返回当前时间(以毫秒为单位)。请注意,虽然*返回值的时间单位是毫秒,但是*值的粒度
取决于基础*操作系统,并且可能更大。例如,许多*操作系统以数十*毫秒为单位测量时间。

* <p>有关*“计算机时间”和协调世界时(UTC)之间可能出现的细微差异的讨论,请参见类
* <code> Date </ code>的描述。

2,解读

currentTimeMillis()

   (1)从源码中可以看到,这个方式是一个native方法,该值由底层提供。

   (2)该方法可以用来计算当前日期,当前星期几等,与Date的换算非常方便,JDK提供了相关的接口来换算。

   (3)通过该方法获取的值的依据是当前系统的日期和时间,可以在系统设置中进行设置和修改。

nanoTime()

(1)该方法也是一个本地方法,返回值由底层提供。

(2)如注释中所说,该方法从java 1.5开始引入。 

(3)该方法所基于的时间是随机的,但在同一个JVM中,不同的地方使用的原点时间是一样的。

3,区别与选择

(1)System.nanoTime()的精确度更高一些,如今的硬件设备性能越来越好,如果要更精密计算执行某行代码或者某块代码所消耗的时间,该方法会测量得更精确。开发者可以根据需要的精确度来选择用哪一个方法。

(2)单独获取System.nanoTime()没有什么意义,因为该值是随机的,无法表示当前的时间。如果要记录当前时间点,用System.currentTimeMills()。

(3)System.currentTimeMills()得到的值能够和Date类方便地转换,jdk提供了多个接口来实现;但是System.nanoTime()则不行。

(4) System.currentTimeMills()的值是基于系统时间的,可以人为地进行修改;而System.nanoTime()则不能,所以如文章开头笔者碰到的问题一样,如果需要根据时间差来过滤某些频繁的操作,用System.nanoTime()会比较合适。
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页