Это 28-й день моего участия в Gengwen Challenge.Подробности о мероприятии:Обновить вызов.
Сразу после предыдущегоПривет, можешь рассказать о ключевом слове volatile? (три)
4.5 Барьер памяти
упомянутый вышеИзменение порядка инструкций создает проблемы с видимостью, решение заключается в использованиибарьер памяти. Что такое барьер памяти?
Барьер памяти — это набор инструкций процессора (зависящих от оборудования), которые накладывают некоторые ограничения на порядок операций с памятью. Может использоваться для реализации многопоточного доступа к одному и тому же ресурсу в памяти.
4.5.1 Анализ барьеров памяти с помощью инструмента Hsdis
Hsdis
это библиотека дизассемблирования, используемая вJava
анализ времени выполненияJIT
Код, сгенерированный компилятором. этоdll(动态链接库)
файл, поставить${JAVA_HOME}/jre/bin/server
используется в каталоге. Мы используем этот инструмент для сравнения переменных перед добавлениемvolatile
Различия между инструкциями по сборке с ключевыми словами и без них.
первый вJava
конфигурация каталога установкиHsdis
Среда, по сути, заключается в том, чтобы поместить два файла в указанную директорию.
в конфигурации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, Не беспокойтесь о повышении зарплаты во время собеседования. Также добро пожаловать, чтобы следовать за мной, я должен быть лучшим человеком.