System.currentTimeMillis是否总是返回值> =之前的调用?

时间:2010-06-05 00:37:23

标签: java linux

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#currentTimeMillis()说:

  

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

我不清楚我是否可以保证此代码将始终打印不断增加(或相同)的数字。

while (1) { 
    System.out.println(System.currentTimeMillis() );
}

5 个答案:

答案 0 :(得分:54)

简短的回答是否定的,System.currentTimeMillis() 单调。它基于系统时间,因此在时钟调整的情况下(例如通过NTP),可以以任何方式(向前或向后)进行变化。

System.nanoTime()是单调的,当且仅当底层平台支持CLOCK_MONOTONIC时 - 请参阅Java bug report 6458294上的评论,以了解在某些情况下这是不正确的

(而且,作为一个额外的轶事,我个人观察(几次)System.currentTimeMillis()在没有时钟调整的情况下,在线程之间运行'向后' - 也就是说,在一个线程中调用该方法线程返回的值低于另一个线程中的调用值,即使它是在“实时”之后按时间顺序发生的)

如果您需要单调来源,在支持单调性的平台上System.nanoTime()是您的最佳选择。

答案 1 :(得分:11)

不,它并不总是> =以前的所有电话。

  • 如果你从同一个帖子中快速连续几次调用它,它可能不会每次都增加(我知道这是> =的一部分,但这种行为通常让人感到惊讶)。

  • 如果你从多个线程快速连续多次调用它,它可以做任何事情 - 它可以在线程上稍微回溯一小段时间,具体取决于实现和随机机会。

  • 最严重的是,如果用户(罕见)或NTP同步(可能是常见的)调整系统时钟,则该值可能会大量返回。

答案 2 :(得分:8)

基于用户可能在两次调用之间改变系统时间这一事实,保证不可能增加

除此之外,它应该保持增长,因为它代表了自纪元以来的毫秒数。如果这是正常的“挂机时间”,您将不得不担心闰日或夏令时转换的时间变化。

答案 3 :(得分:7)

如果你想要一个单调增加的值,你可以做类似的事情。

public enum Time {
    ;
    private static long lastTime;
    public synchronized static long increasingTimeMillis() {
        long now = System.currentTimeMillis();
        if (now > lastTime)
            return lastTime = now;
        return ++lastTime;
    }
}

只要你每秒拨打的次数不到一千次,你的增加时间就不会偏离实时太远,但会是独一无二的。 (即使重新启动应用程序,这也可以工作)

答案 4 :(得分:1)

@Mark Rushakoff是对的; nanoTime()可能稍微更可靠。

附录:注意@Steven Schlansker引用的这些caveats