Java的nanoTime()

简介: java有两个获取和时间相关的秒数方法,一个是广泛使用的 System.currentTimeMillis()   返回的是从一个长整型结果,表示毫秒。 另一个是 System.nanoTime()   返回的是纳秒。

java有两个获取和时间相关的秒数方法,一个是广泛使用的

System.currentTimeMillis()
 

返回的是从一个长整型结果,表示毫秒。

另一个是

System.nanoTime()
 

返回的是纳秒。

 

“纳”这个单位 一般不是第一次见。前几年相当火爆的“纳米”和他是同一级别。纳表示的是10的-9次方。在真空中,光一纳秒也只能传播30厘米。

比纳秒大一级别的是微秒,10的-6次方;然后是就是毫秒,10的-3次方。

纳秒下面还有皮秒、飞秒等。

 

既然纳秒比毫秒高10的6次方精度,那么他们的比值就应该是10的6次方。然而并非如此。

看下面的代码

public static void main(String[] args) {
    long l = System.currentTimeMillis();
    Date date = new Date(l);
    System.out.println(l);
    System.out.println(date);
}
 

最后输出的当前时间。

大家可能都知道毫秒方法返回的是自1970年到现在的毫秒数。而Java的日期也是如此,所以他俩是等值的。

但是使用纳秒方法的输出可能让我们丈二和尚摸不着头脑:

public static void main(String[] args) {
    long l = System.nanoTime();
    Date date = new Date(l / 1_000_000);
    System.out.println(l);
    System.out.println(date);
}
 

这个输出在不同的机器上可能不一样,我的输出是Fri Jan 02 07:58:38 CST 1970

 

为什么会这样?

根据纳秒方法的注释:

Returns the current value of the running Java Virtual Machine's high-resolution time source, in nanoseconds.
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 origin 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.

翻译一下就是:返回当前JVM的高精度时间。该方法只能用来测量时段而和系统时间无关。它的返回值是从某个固定但随意的时间点开始的(可能是未来的某个时间)。不同的JVM使用的起点可能不同。

 

这样有点恐怖的是我们相同的代码在不同机器运行导致结果可能不同。

所以它很少用来计算。通常都是测量。

 

下面写一个程序来反映他和毫秒方法的关系。

  Lists.newArrayList(1,2,3,4,5,6,7,8,9).parallelStream().forEach(i -> {
        long m = System.currentTimeMillis();
        long n = System.nanoTime();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ignored) {
        }
        long m1 = System.currentTimeMillis();
        long n1 = System.nanoTime();
        long m0 = m1 - m;
        long n0 = n1 - n;

        System.out.println(i + " -- " + (n0 / m0));
    });
}
 

输出如下:

3 -- 999756
6 -- 1000129
2 -- 999984
4 -- 999868
5 -- 999019
1 -- 999100
8 -- 999768
7 -- 999753
9 -- 1000139

不同的测试可能结果不同,不过可以看到,这个比值大约是10的6次方。

目录
相关文章
|
Cloud Native Oracle Java
李三红:Java30年,未来在哪里?
李三红:Java30年,未来在哪里?
327 0
|
存储 Java
1101 B是A的多少倍(JAVA)
设一个数 A 的最低 D 位形成的数是 ad​。如果把 ad​ 截下来移到 A 的最高位前面,就形成了一个新的数 B。B 是 A 的多少倍?例如将 12345 的最低 2 位 45 截下来放到 123 的前面,就得到 45123,它约是 12345 的 3.66 倍。
 1101 B是A的多少倍(JAVA)
|
Java
Java常见的坑(二)
你猜上述程序输出的是什么? 是 ABC easy as 123 吗? 你执行了输出操作,你才发现输出的是 ABC easy as [C@6e8cf4c6 ,这么一串丑陋的数字是什么鬼? 实际上我们知道字符串与任何数值的相加都会变为字符串,上述事例也不例外, numbers输出其实实际上是调用了Object.toString()方法,让numbers转变为'[c' + '@' + 无符号的十六进制数。
45 0
|
算法 Java Linux
Java ConcurrentSkipListMap 实现
本文目前只是简单地介绍了 Java 并发容器中 ConcurrentSkipListMap 的实现方式,后续会考虑拓展本文,从源码的角度进行详细的分析。
Java ConcurrentSkipListMap 实现
|
人工智能 Java 程序员
6月来了,Java还是第一!
今天是2019年6月1号,栈长祝各位小程序猿们节日快乐。
6月来了,Java还是第一!
|
Java 应用服务中间件 数据库连接
java导读
导读:      我们学习Java大概有3个方向,第一,桌面系统,包括C/S结构;第二,J2ME,面向无限领域,很有潜力的家伙,看看中国的手机用户就知道了。第三,面向企业应用、计算的平台,J2EE.      初次涉及Java领域,感觉到Java入门是好像没有C,C++入门快,工具也没有什么Turbo C,Visual C++好用(自己的破机器实在陪不起JBuilder,贪婪的家伙,以后一定要收拾她)。
1271 0
|
测试技术
JAVA-1009. 说反话 (20)
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。 输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。
1059 0
|
Java
java培训哪些事
我希望大家记住,问题是有的,任何一个行业都不可能避免,但是这些问题不是让我们否定一个行业的理由,毕竟选择权在我们自己的手里,往往我们的选择会决定一个行业市场的形成与灭亡。很多时候,我们要依靠自己的选择和行动来改变一个市场,来改变一个行业!
1572 0