-System.nanoTime()+ System.nanoTime()保证是> = 0?

时间:2012-01-13 16:19:18

标签: java time

大家好我有一段看起来像这样的代码:

public class Test {
    public static void main(String args[]) {
        long a = System.currentTimeMillis(); // line 1
        long b = System.currentTimeMillis(); // line 2
        assert b - a >= 0;

        long y = System.nanoTime(); // line 5
        long z = System.nanoTime(); // line 6
    }
}

所以IERS表示下一个闰秒是在2012年6月11日开始之后立即发生的 11:59.9。

我想知道我是否说得对,如果第1行是在 30 th 2012年6月11:59.9 之后的0.9秒运行 1 < sup> st 2012年7月00:00.0

第2行在第1行后的0.1秒运行,

b - a的结果可能否定? (-900毫秒)

如果是这种情况,如果第5行是在 30 th 2012年6月11:59.9 之后的0.9秒运行 1 st 2012年7月00:00.0

第6行在第5行后的0.1秒运行,

z - y的结果可能否定? (-900,000,000纳秒?)

5 个答案:

答案 0 :(得分:8)

System.nanoTime 应该单调增加 - 如果您有两次调用,AB,并且A发生之前B,然后是A <= B。但实际上,你可以实际观察nanoTime向后“。”

nanoTime由CPU上的内部计数器决定,其开始时间基本上是任意的(这就是为什么它不能用于确定挂钟时间)。这可能会导致多核环境出现问题,因为一个核心的内部计时器可能与另一个核心的起点不同。 Hotspot试图弥补这一点,但它并不总是成功,因此事实上你可以看到nanoTime在某些情况下向后滴答。

在并发兴趣邮件列表上有一个recent discussion。请特别参阅this email链接到this bug reportthis email,其中讨论了解决方法(虽然我不确定原因但似乎不起作用)。错误报告有相当多的细节。

答案 1 :(得分:3)

  

我说得对,如果第1行在2012年6月30日之后的0.9秒运行11:59.9转到2012年7月1日00:00.0,

如果未调整时钟,则在30th June 2012 11:59.91st July 2012 00:00.8

后0.9秒
  

b - a的结果会是否定的?

currentTimeMillis()是自1970年以来以毫秒为单位的时间。它不会在当天开始时重置。或者在你一生中的任何时候。

  

z - y的结果会是否定的?

nanoTime()也不是从一天开始以来的时间。在许多JVM / OS上,它是自上次重置CPU以来的纳秒数。


并非所有操作系统都提供相同的分辨率。例如RHEL / Centos 5.x仅提供微秒级分辨率。这意味着你可以连续多次调用给出相同的值(微秒)

long a = System.currentTimeMillis(); // line 1
long b = System.currentTimeMillis(); // line 2
assert b - a >= 0;

只要通过向后转动来纠正时间,这将会倒退。例如通过NTP。

long y = System.nanoTime(); // line 5
long z = System.nanoTime(); // line 6

这将在具有多个套接字的系统上倒退,这对于不同套接字中的时间戳计数器的差异不正确。例如如果您使用的是Windows XP且有两个套接字,则可以看到在套接字之间切换线程时向前或向后跳跃的差异为4,000,000。

答案 2 :(得分:3)

不,你错了。因为这不是当前时间的毫秒,而是从1970年开始的总毫秒数。

它们可能是相同的,但后来不会早于。但是,如果NTP守护程序正在执行其工作,则可能会在某个时刻调整系统时钟。

nanoTime是更可靠的方式,因为它不依赖于系统时钟,不应通过时钟调整来改变。

答案 3 :(得分:2)

我对wiki页面的阅读与你的相同:currentTimeMillis()可以由于闰秒而倒退。

(为什么他们把这个优秀的天文问题带到民用时间?如果太阳中午停止几秒钟就没有平民关心;实际上没有人利用当地时间开始;同一时区的人们可以观察太阳中午的不同之处1小时。在一个没有时区的大国,差异可能是几个小时。)

答案 4 :(得分:1)

  

-System.nanoTime()+ System.nanoTime()保证为&gt; = 0?

是。这是一个计时器,而不是任何绝对时间,根据其文档,它返回最精确的可用系统计时器的当前值,以纳秒为单位。返回的值表示自固定但任意时间以来的纳秒。时间因为某个固定时间不会倒退(虽然292年之后差异会溢出,但这不是一个实际问题。另外,正如Peter Lawrey指出的那样,Windows XP has a bug that breaks nanotime's guarantees)。

System.currentTimeMillis()完全不同。它返回从计算机时钟获得的绝对时间(自1970年以来的毫秒数),可以随时调整。