Подтвердить что ты не робот

Is -System.nanoTime() + System.nanoTime() гарантированно >= 0?

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

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 June 2012 11: 59.9.

Мне было интересно, могу ли я сказать, что если строка 1 запускается через 0,9 секунды после 30 th Июнь 2012 11: 59,9 превращает 1 st Июль 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.0,

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

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

4b9b3361

Ответ 1

System.nanoTime должно быть монотонно возрастающим - если у вас есть два вызова к нему, A и B, а A произойдет до B, тогда A <= B. Но на практике вы можете наблюдать nanoTime "назад".

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

Об этом в concurrency -interest список рассылки было обсуждение . См., В частности, это письмо, которое ссылается на этот отчет об ошибках и это письмо, в котором говорится об обходном пути (который, похоже, не работает, хотя я не уверен, почему). Отчет об ошибке содержит множество подробностей.

Ответ 2

Можно ли сказать, что если линия 1 запускается через 0,9 секунды после 30 июня 2012 года 11: 59,9 очереди 1 июля 2012 года 00: 00.0,

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

Результат b - a будет отрицательным?

CurrentTimeMillis() - это время в миллисекундах с 1970 года. Оно не reset в начале дня. Или любое время в вашей жизни.

Результат z-y был бы отрицательным?

nanoTime() - это не время с начала дня. На многих JVM/OS существует число nano-секунд, так как процессор был последним reset.


Не все ОС имеют одинаковое разрешение. например 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 вперед или назад, поскольку она переключает поток между сокетами.

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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

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