Не паникуйте при встрече | Здравствуйте, можете рассказать о ключевом слове volatile? (Четыре)

Java опрос
Не паникуйте при встрече | Здравствуйте, можете рассказать о ключевом слове volatile? (Четыре)

Это 28-й день моего участия в Gengwen Challenge.Подробности о мероприятии:Обновить вызов.
Сразу после предыдущегоПривет, можешь рассказать о ключевом слове volatile? (три)

4.5 Барьер памяти

упомянутый вышеИзменение порядка инструкций создает проблемы с видимостью, решение заключается в использованиибарьер памяти. Что такое барьер памяти?

Барьер памяти — это набор инструкций процессора (зависящих от оборудования), которые накладывают некоторые ограничения на порядок операций с памятью. Может использоваться для реализации многопоточного доступа к одному и тому же ресурсу в памяти.

4.5.1 Анализ барьеров памяти с помощью инструмента Hsdis

Hsdisэто библиотека дизассемблирования, используемая вJavaанализ времени выполненияJITКод, сгенерированный компилятором. этоdll(动态链接库)файл, поставить${JAVA_HOME}/jre/bin/serverиспользуется в каталоге. Мы используем этот инструмент для сравнения переменных перед добавлениемvolatileРазличия между инструкциями по сборке с ключевыми словами и без них.

первый вJavaконфигурация каталога установкиHsdisСреда, по сути, заключается в том, чтобы поместить два файла в указанную директорию.

hsdis.png

в конфигурацииHsdisсреду, после запуска программыVM OptionsДобавьте следующие параметры.

-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*VolatileExample.*
  • -XX:+UnlockDiagnosticVMOptionsПараметр представляет собой включение режима диагностики для упрощения печати.PrintAssemblyкласс информации.
  • -XX:+PrintAssemblyПараметр представляет вывод двоичной информации о своевременной компиляции.
  • XX:CompileCommand=compileonly,*VolatileExample.*Этот фильтр представления отображает только ту информацию, которая удовлетворяет регулярному выражению *VolatileExample.*.

Затем запускаем пример из главы 2VolatileExample.

Откройте для себя плюсvolatileукрашенная переменнаяrunИнструкции по сборке есть

0x0000000003565073: lock add dword ptr [rsp],0h  ;*putstatic run

не добавленоvolatileукрашенная переменнаяrunИнструкции по сборке есть

  0x00000000030e5ceb: push    0ffffffffc4834801h  ;*putstatic run

Вы можете четко видеть разницу, естьvolatileМодифицированная переменная, еще однаlockинструкция.lockЭто инструкция управления сборкой, эквивалентная реализации барьера памяти.

4.5.2 Подробное объяснение барьеров памяти

заJavaязык, барьеры памяти не являются непосредственноJVMвыставлены для использования, ноJVMСогласно семантике кода, он вставляется в базовую инструкцию запуска. Например, приведенный выше анализ практики показывает, что добавлениеvolatileКлючевое слово модифицирует переменную, а дальше будет инструкция по сборкеlockинструкция.

Инструкции барьера памяти, предоставляемые разным оборудованием для внешнего использования, различаются. такие, как мы знаемX86компьютерное оборудование, обеспечивающееIfence(读屏障),Sfence(写屏障),mfence(全屏障)Эти виды инструкций создают барьеры памяти.

  • Барьер чтения (Load Memory Barrier) — это операция чтения после барьера чтения, которая выполняется после барьера чтения. Эта инструкция должна выполняться вместе с барьером записи.В результате обновление памяти перед барьером записи становится видимым для операции чтения после барьера чтения. Суть этого в том, что перед чтением барьера применяются все инструкции по операциям инвалидации, которые уже находятся в очереди инвалидации.
  • Барьер записи (Store Memory Barrier) — это операция записи перед барьером записи, которая должна бытьStore BufferСинхронно сбрасывать в основную память. В результате операции чтения и записи после барьера записи могут видеть обновление памяти до барьера записи.
  • Полный барьер (Full Memory Barrier) — это операции чтения и записи до полного барьера, а генерируемые им обновления памяти видны операциям чтения и записи после барьера.

Поэтому для примера в разделе 4.4.3 мы просто модифицируем его, добавив барьер памяти для обеспечения видимости.

int value =1;
bool finish = false;

void runOnCPU1(){
  value = 2;
  storeMemoryBarrier();//伪代码,写屏障,强制变量刷新到主存
  finish = true;
}

void runOnCPU2(){
  if(finish){
    loadMemoryBarrier();//伪代码,读屏障,获取多线程环境下最新的变量值
	assert value == 2;
  }
}

Итак, подводя итог,JavaКомпилятор вставляет некоторые барьеры памяти до и после операций чтения и записи поля volatile, что решает проблему переупорядочивания инструкций. Следует особо отметить, что дляJavaЯзык, настоящий герой решения переупорядочивания инструкцийJMM(Java Memory Model).
JMMВ качестве моста для связи с базовой реализацией сложного оборудования он предоставляет несколько разумных методов отключения кэширования и переупорядочивания, а затем преобразует их в определенные во время компиляции.CPUинструкция, решено可见性а также有序性проблемы, конкретные методы включаютsynchronized,volatile,final. В этой главе мы не будем вдаваться в подробности, а подробно проанализируем их позже.
Длина длинная, чтобы продолжить чтение, пожалуйста, нажмите[Не паникуйте при встрече] Здравствуйте, можете рассказать о ключевом слове volatile? (пять)


Брат, не паникуй! Не стесняйтесь оставлять лайки, обсуждать и комментировать. Добро пожаловать в колонку интервьюНе паникуйте, когда сталкиваетесь | Параллельное программирование на Java, Не беспокойтесь о повышении зарплаты во время собеседования. Также добро пожаловать, чтобы следовать за мной, я должен быть лучшим человеком.