Гарантируется ли -System.nanoTime () + System.nanoTime ()> = 0? - PullRequest
12 голосов
/ 13 января 2012

Привет всем, у меня есть кусок кода, который выглядит следующим образом:

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 заявил, что следующая високосная секунда должна произойти сразу после 30 th Июнь 2012 11: 59,9.

Мне было интересно, могу ли я сказать, что если строка 1 будет запущена через 0,9 секунды после 30 th Июнь 2012 11: 59,9 повороты 1 ст июль 2012 00: 00,0 ,

И строка 2 запускается через 0,1 секунды после строки 1,

Результат b - a может быть отрицательным ? (-900 миллисекунд)

Если это так, верно ли, что строка 5 запускается через 0,9 секунды после 30 th Июнь 2012 11: 59,9 поворотов 1 st июль 2012 г. 00:00

И строка 6 запускается через 0,1 секунды после строки 5,

Результат z - y может быть отрицательным ? (-900 000 000 наносекунд?)

Ответы [ 5 ]

8 голосов
/ 13 января 2012

System.nanoTime должно * монотонно увеличиваться - если у вас есть два вызова к нему, A и B и A происходит до B, затем A <= B. Но на практике вы можете наблюдать, как nanoTime движется назад.

nanoTime определяется внутренним счетчиком ЦПУ, время запуска которого по существу произвольно (поэтому его нельзя использовать для определения времени настенных часов). Это может вызвать проблему в многоядерной среде, так как внутренний таймер одного ядра может иметь отправную точку, отличную от другой. Hotspot пытается это компенсировать, но это не всегда удается, поэтому в некоторых ситуациях вы можете увидеть nanoTime, тикающим в обратном направлении.

* * * * * * * * * * * * * * * * * *. В списке рассылки по интересам, связанным с параллелизмом, недавно было . В частности, смотрите это электронное письмо , которое ссылается на это сообщение об ошибке , и это электронное письмо , в котором говорится об обходном пути (который, похоже, не работает, хотя я ' Я не уверен, почему). Отчет об ошибке содержит довольно много деталей.

3 голосов
/ 13 января 2012

Нет, вы не правы. Потому что это не миллисекундная часть текущего времени, а общие миллисекунды, прошедшие с 1970 года.

Они могут быть такими же, но позже не меньше, чем раньше. Однако, если демон NTP выполняет свою работу, это может произойти, если в какой-то момент системные часы будут настроены.

nanoTime - более надежный способ, поскольку он не зависит от системных часов и не должен изменяться настройками часов.

3 голосов
/ 13 января 2012

Правильно ли мне сказать, что если строка 1 будет запущена через 0,9 секунды после 30 июня 2012 г. 11: 59,9 поворотов 1 июля 2012 г. 00:00,

Если часы не настроены, 0,9 секунды после 30th June 2012 11:59.9 равно 1st July 2012 00:00.8

Результат 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 голосов
/ 13 января 2012

Мое чтение вики-страницы такое же, как и у вас: currentTimeMillis () может вернуться назад из-за високосной секунды.

(Почему они привели эту прекрасную астрономическую проблему в гражданское время? Гражданскому небезразличному, если в солнечный полденьотключается на несколько секунд, фактически никто не использует местное время для начала; люди в одном и том же часовом поясе могут наблюдать, как солнечные полдни различаются на 1 час, а в большой стране без часового пояса разница может составлять часы.)

1 голос
/ 13 января 2012

-System.nanoTime () + System.nanoTime () гарантированно будет> = 0?

Да. Это таймер, а не абсолютное времяи, согласно документам, он возвращает текущее значение наиболее точного доступного системного таймера в наносекундах.Возвращаемое значение представляет наносекунды с некоторого фиксированного, но произвольного времени. Время с некоторого фиксированного времени не возвращается назад (хотя через 292 года разница будет переполнена, но это вряд ли является практической проблемой. Кроме того, как отметил Питер Лори, В Windows XP есть ошибка, которая нарушает гарантии nanotime ).

System.currentTimeMillis () полностью отличается. Возвращает абсолютное время (миллисекунды с 1970 года), которое полученоот часов компьютера, которые можно отрегулировать в любое время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...