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

198*_*ual 45 java linux

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

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

我不清楚我是否保证这段代码将始终打印不断增加(或相同)的数字.

while (1) { 
    System.out.println(System.currentTimeMillis() );
}
Run Code Online (Sandbox Code Playgroud)

Cow*_*wan 59

简短的回答是否定的,System.currentTimeMillis()不是单调的.它是基于系统时间,并且因此可经受变化的时钟调整的情况下,或者方法(向前或向后)(例如,经由NTP).

System.nanoTime()当且仅当底层平台支持时才是单调的CLOCK_MONOTONIC- 请参阅有关Java错误报告6458294的注释,以便在某些情况下进行良好的写入,这是不正确的.

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

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

  • 简单的版本是我们有一些计时工作,它们存储了`long start = System.currentTimeMillis()`,然后启动另一个线程来完成工作,它本身在最后执行了`long end = System.currentTimeMillis()`,并减去了两个.在非常短期的工作中,这种差异(并非罕见)是负面的.这让我很困惑,直到我做了一些研究并挖掘了代码.:) (4认同)

Sea*_*lly 12

不,它不会总是> =以前所有的电话.

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

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

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


Mar*_*off 9

基于用户可能潜在地改变呼叫之间的系统时间这一事实,不可能保证增加.

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


Pet*_*rey 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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