Если переменная является энергонезависимой, то компилятор и ЦП могут свободно упорядочивать инструкции по своему усмотрению для оптимизации производительности.
Если переменная теперь объявлена как volatile, то компилятор больше не пытается оптимизировать доступ (чтение и запись) к этой переменной. Однако может продолжать оптимизировать доступ для других переменных.
Во время выполнения при обращении к энергозависимой переменной JVM генерирует соответствующие инструкции барьера памяти для CPU. Барьер памяти служит той же цели - ЦПУ также не позволяет переупорядочивать инструкции.
Когда переменная volatile записывается (потоком A), все записи в любую другую переменную завершаются (или, по крайней мере, будут выглядеть) и становятся видимыми для A перед записью в переменную volatile; это часто происходит из-за инструкции по записи в память. Аналогично, любое чтение других переменных будет завершено (или будет выглядеть) до того, как
читать (по теме B); это часто происходит из-за инструкции по чтению из памяти. Такое упорядочение инструкций, которое обеспечивается барьером (-ами), будет означать, что все записи, видимые для A, будут видны B. Однако это не означает, что какого-либо переупорядочения инструкций не произошло (компилятор мог выполнить переупорядочение для других инструкций); это просто означает, что если произошла какая-либо запись, видимая для A, она будет видна для B. Проще говоря, это означает, что строгий программный порядок не поддерживается.
Я укажу на эту запись в Барьеры памяти и параллелизм JVM , если вы хотите понять, как JVM выдает инструкции по барьеру памяти, более подробно.
Смежные вопросы
- Что такое забор памяти?
- Какие уловки делает процессор для оптимизации кода?