将System.currentTimeMillis总是返回一个值> =以前的调用?
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#currentTimeMillis()说:
以毫秒为单位返回当前时间。 请注意,虽然返回值的时间单位是毫秒,但是值的粒度取决于底层操作系统,可能会更大。 例如,许多操作系统以几十毫秒为单位来测量时间。
我不清楚,如果我保证,这个代码将永远打印不断增加(或相同)的数字。
while (1) { System.out.println(System.currentTimeMillis() ); }
简短的回答是否, System.currentTimeMillis()
不是单调的。 它基于系统时间,因此在时钟调整的情况下(例如,通过NTP )可以以任何方式(向前或向后)变化。
System.nanoTime()
是单调的,当且仅当底层平台支持CLOCK_MONOTONIC
– 请在Java错误报告6458294上查看有关在某些情况下是否正确的良好写法的评论。
(另外,我还亲自观察过(多次) System.currentTimeMillis()
,在没有时钟调整的情况下,在线程之间运行“向后”,也就是说,在一个线程中对该方法的调用返回比在另一个线程中的调用更低的值,即使它在“实时”之后按时间顺序发生)。
如果您需要单调来源,在支持单调性的平台上的System.nanoTime()
是您的最佳select。
不,它不会总是>以前的所有电话。
-
如果你从同一个线程快速地连续多次调用它(我知道这是> =的一部分,但这种行为往往让人惊讶),它可能不会每次都增加。
-
如果你从多个线程快速连续多次调用它,它可能会做很多事情 – 它可能会稍微回退一小段时间,取决于实现和随机机会。
-
最严重的是,如果用户(罕见)或NTP同步(可能是普通的)调整系统时钟,则该值可能会大量回溯。
根据用户可能会在两次呼叫之间改变系统时间的事实,不可能保证增加。
除此之外,它应该保持增长,因为它代表了自时代以来的毫秒数。 如果这是一个正常的“rest时间”,你将不得不担心闰日的时间变化或夏时制转换。
如果你想要一个单调递增的值,你可以做类似的事情。
public enum Time { ; private static long lastTime; public synchronized static long increasingTimeMillis() { long now = System.currentTimeMillis(); if (now > lastTime) return lastTime = now; return ++lastTime; } }
只要你每秒钟不到一千次,你的增长时间就不会偏离实时,而是独一无二的。 (即使您重新启动应用程序,这也可以工作)
@Mark Rushakoff是对的; nanoTime()
可能稍微可靠一些。
附录:请注意 @Steven Schlansker引用的这些注意事项 。