http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#currentTimeMillis()说:
以毫秒为单位返回当前时间。请注意,虽然返回值的时间单位是毫秒,但值的粒度取决于底层操作系统,并且可能更大。例如,许多操作系统以几十毫秒为单位测量时间。
我不清楚我是否可以保证此代码将始终打印不断增加(或相同)的数字。
while (1) {
System.out.println(System.currentTimeMillis() );
}
答案 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。