См. Эту статью Андрея Александреску: « volatile - лучший друг многопоточного программиста »
Ключевое слово volatile было разработано для предотвращения оптимизации компилятора, которая может сделать код некорректным при наличии определенных асинхронных событий. Например, если вы объявляете примитивную переменную как volatile , компилятору не разрешается кэшировать ее в регистре - обычная оптимизация, которая будет иметь катастрофические последствия, если эта переменная будет разделена между несколькими потоками. Таким образом, общее правило: если у вас есть переменные примитивного типа, которые должны совместно использоваться несколькими потоками, объявите эти переменные volatile . Но вы можете сделать гораздо больше с этим ключевым словом: вы можете использовать его для перехвата кода, который не является потокобезопасным, и вы можете сделать это во время компиляции. Эта статья показывает, как это делается; решение включает в себя простой интеллектуальный указатель, который также упрощает сериализацию критических участков кода.
Статья относится как к C
, так и к C++
.
Также см. Статью « C ++ и опасности двойной проверки блокировки » Скотта Мейерса и Андрея Александреску:
Так что при работе с некоторыми областями памяти (например, памятью) сопоставленные порты или память, на которые ссылаются ISR [процедуры обработки прерываний]), некоторые оптимизации должны быть приостановлены. volatile существует для указания специального режима для таких расположений, а именно: (1) содержимое переменной volatile «нестабильно» (может изменяться неизвестным для компилятора способом), (2) все записи в volatile данные «наблюдаемы», поэтому они должны выполняться неукоснительно, и (3) все операции с изменчивыми данными выполняются в той последовательности, в которой они появляются в исходном коде. Первые два правила обеспечивают правильное чтение и письмо. Последний позволяет реализовать протоколы ввода / вывода, которые смешивают ввод и вывод. Это неофициально, что волатильные гарантии C и C ++.
Надеюсь, что нет - это то, что я использую, когда надеваю 'Не использовать nanoTime ()
.
Помимо System.nanoTime ()
, JMX, вероятно, является лучшим жизнеспособным вариантом:
java.lang.management.ManagementFactory.getThreadMXBean()
вы можете запросить текущее время процессора потока (измеренное в наносекундах, но не с помощью nano секундная точность, как для System.nanoTime
())
Одна ошибка что он измеряет прошедшее время в реальном времени, а не время процессора, поэтому он очень зависит от загрузки системы. Это нормально, если вы используете бесплатную машину, но иногда может дать интересные результаты, если другие процессы пытаются выполнить работу.
В этой статье есть интересное решение проблемы.
До Java 1.5 существовал только System.currentTimeMillis. Однако степень детализации значения зависит от базовой операционной системы и может быть большой. В Windows XP я иногда получал пропуски в 20 мс. Я слышал, что Linux намного лучше с пробелами в диапазоне 1-2 мс.
В Java 1.5 вы также можете использовать System.nanoTime. У меня никогда не было проблем с этим.