Оскільки Java 7 System.nanoTime()
гарантована в безпеці за специфікаціями JDK. System.nanoTime()
Javadoc дає зрозуміти, що всі спостережувані виклики в межах JVM (тобто в усіх потоках) є монотонними:
Повернене значення являє собою наносекунд, оскільки деякий фіксований, але довільний час початку (можливо, у майбутньому, тому значення можуть бути негативними). Те саме походження використовується всіма викликами цього методу в екземплярі віртуальної машини Java; інші екземпляри віртуальної машини, ймовірно, використовують інше походження.
Реалізація JVM / JDK несе відповідальність за виправлення невідповідностей, які могли бути помічені під час виклику базових утиліт ОС (наприклад, зазначених у відповіді Тома Андерсона ).
Більшість інших старих відповідей на це питання (написане у 2009–2012 рр.) Виражають FUD, що, ймовірно, стосується Java 5 або Java 6, але більше не стосується сучасних версій Java.
Однак варто зазначити, що, незважаючи на гарантію nanoTime()
безпеки JDK, у OpenJDK було кілька помилок, завдяки чому вона не підтримувала цю гарантію на певних платформах або за певних обставин (наприклад, JDK-8040140 , JDK-8184271 ). У OpenJDK wrt немає відкритих (відомих) помилокnanoTime()
, але виявлення нової такої помилки чи регресія в новій версії OpenJDK нікого не повинно шокувати.
Зважаючи на це, код, який використовується nanoTime()
для блокування приуроченого часу, інтервального очікування, тайм-аутів тощо, бажано вважати негативними різницями у часі (таймаутами) як нулі, а не викидами. Ця практика також є кращою , оскільки він узгоджується з поведінкою всіх синхронізованих методів очікування у всіх класах в java.util.concurrent.*
, наприклад Semaphore.tryAcquire()
, Lock.tryLock()
,BlockingQueue.poll()
і т.д.
Тим не менш, nanoTime()
все ж слід віддавати перевагу впровадженню тимчасового блокування, інтервального очікування, тайм-аутів тощо, currentTimeMillis()
оскільки останні є предметом явища "час, що йде назад" (наприклад, через корекцію часу на сервері), тобто currentTimeMillis()
не підходить для вимірювання часових інтервалів. зовсім. Дивіться цю відповідь для отримання додаткової інформації.
Замість використання nanoTime()
для вимірювання часу виконання коду безпосередньо, спеціалізовані бенчмаркінг структури і профайлери переважно повинні бути використані, наприклад , JMH і асинхронної-Profiler в режимі профілювання на стіні годинник .