инструкция
Позавчера я поделился статьей об Али.Распространенные сомнения и ловушки в Javaстатья, некоторые люди говорили, что это было давно, может быть, я просто заметил это, и прочитав, я обнаружил, что содержание очень хорошее, мне также нужно сделать паузу и подумать о нескольких. Если есть шанс в будущем я запишу видео и выложу его в этом ppt, я поделюсь с вами всем содержанием в соответствии с моим пониманием и знаниями.
Если вы не видели его раньше, пожалуйста, посмотрите:Распространенные сомнения и ловушки в Java, если вам нужно получитьполный ppt, вы можете ответить в диалоговом окне официального аккаунта: "PPT"Вы можете получить полный файл, если вы обнаружите, что вам нужно некоторое время подумать, когда вы видите в нем точки знаний, то это означает, что вы не знакомы с ним, и вы должны пойти, чтобы дополнить соответствующий базовый знание.
тема
Лично я всегда думал:Знания, связанные с сетями и параллелизмом, сложнее, чем другие знания в области программирования, в основном потому, что их нелегко отлаживать и они включают слишком много контента!
Итак, сегодня я поделюсь контентом, связанным с параллелизмом. Я верю, что каждый что-то получит, внимательно его прочитав.
Можете ли вы сначала взглянуть на эту проблему и посмотреть, есть ли проблема с этим? Есть ли проблема?
Если вы задержались на этом вопросе более чем на 5 секунд, значит, вы еще немного расплывчаты в этом знании, и вам нужно его закрепить, давайте проанализируем его вместе!
в заключении
Выполнять операции set и get одновременно с несколькими потоками,Поток вызывает метод set, и поток B не обязательно сможет увидеть это изменение! ! !
анализировать
Этот класс очень простой, в нем одно свойство, а методов два: методы get и set, один используется для установки значения свойства, другой используется для получения значения свойства, и к свойству добавляется synchronized метод настройки.
Неявная информация:Выполнять операции set и get одновременно с несколькими потоками,Поток A вызывает метод set, может ли поток B его воспринять? ? ?
Было сказано, что,Возникает вопрос, может ли синхронизация гарантировать видимость в только что упомянутом контексте! ! !
Использование ключевого слова синхронизировано
- Укажите объект блокировки: Чтобы заблокировать данный объект, вам необходимо получить блокировку данного объекта перед вводом кода синхронизации.
- Воздействие непосредственно на метод экземпляра: это эквивалентно блокировке текущего экземпляра, и блокировка текущего экземпляра должна быть получена до ввода кода синхронизации.
- Прямое действие на статические методы: эквивалентно блокировке текущего класса, причем блокировку текущего класса необходимо получить до ввода кода синхронизации.
Его задача — заблокировать код, который нужно синхронизировать, чтобы только один поток мог одновременно войти в синхронизированный блок (фактически пессимистичная стратегия) для обеспечения безопасности между потоками.
Отсюда мы можем узнать, что то, что нам нужно проанализировать, относится ко второму типу ситуации, то есть, если несколько потоков выполняют метод set одновременно, из-за существования блокировок будет выполнена операция set. один за другим, и это потокобезопасно, но метод get не заблокирован, что означает, что если поток A выполняет set, а поток B может выполнять операцию get. И несколько потоков могут выполнять операции получения одновременно, но одновременно может быть только одна операция установки.
Модель памяти Java происходит до принципа
Модель памяти JSR-133 использует концепцию «происходит до» для иллюстрации видимости памяти между операциями. В JMM, еслиРезультат выполнения одной операции должен быть виден другой операции, то между этими двумя операциями должна быть связь «происходит до». Две упомянутые здесь операции могут выполняться либо внутри потока, либо между разными потоками.
Правила «происходит до», тесно связанные с программистами, следующие:
- Правила порядка выполнения программы: каждая операция в потоке выполняется до любых последующих операций в этом потоке.
- Правила блокировки монитора: разблокировка монитора происходит до последующей блокировки монитора.
- Правила для изменчивых переменных: Запись в изменчивое поле происходит до любых последующих чтений изменчивого поля.
- Переходный: если А происходит раньше В, а В происходит раньше С, то А происходит раньше С.
Обратите внимание, что между двумя операциями существует отношение «происходит до», что не означает, что первая операция должна быть выполнена до второй операции! «случается-прежде» требует только, чтобы предыдущая операция (результат выполнения) была видна следующей операции, а первая была видна и упорядочена перед второй операцией.
В том числеПравила блокировки монитора: разблокировка монитора происходит до последующей блокировки монитора.Это только для метода синхронизированного набора, и в этом отношении нет описания для get.
На самом деле, в этом контексте синхронизированный метод set, обычный метод get, поток вызывает метод set, и поток b не обязательно сможет увидеть это изменение!
Дополнительная память модели памяти Java приветствуется для просмотра:Глубокое понимание модели памяти Java, Написание очень подробное, рекомендуется прочитать несколько раз! ! !
volatile
изменчивая видимость
Принцип «происходит раньше», упомянутый ранее:Правила для изменчивых переменных: Запись в изменчивое поле происходит до любых последующих чтений изменчивого поля.Таким образом, Volatile обеспечивает видимость при многопоточности! ! !
volatile предотвращает переупорядочивание памяти
Ниже приведена таблица изменяемых правил переупорядочения, сформулированных JMM для компилятора:
Чтобы достичь семантики памяти volatile, компилятор вставляет барьеры памяти в последовательность инструкций, чтобы запретить определенные типы переупорядочения процессора при генерации байт-кода.
Ниже приведена стратегия вставки барьера памяти JMM, основанная на консервативной стратегии:
- Вставьте барьер StoreStore перед каждой энергозависимой записью.
- Вставляйте барьер StoreLoad после каждой энергозависимой записи.
- Вставьте барьер LoadLoad после каждого чтения volatile.
- Вставляйте барьер LoadStore после каждого чтения энергозависимых данных.
Ниже приведена схема последовательности инструкций, сгенерированных после того, как операция энергозависимой записи вставлена в барьер памяти в соответствии с консервативной стратегией:
Ниже представлена схематическая диаграмма последовательности команд, сгенерированной после того, как операция чтения энергозависимой памяти вставляется в барьер памяти в соответствии с консервативной стратегией:
Вышеупомянутые стратегии вставки барьера памяти для энергозависимой записи и энергозависимого чтения очень консервативны. При фактическом выполнении, пока семантика памяти volatile-записи-чтения не изменяется, компилятор может опускать ненужные барьеры в каждом конкретном случае.
Дополнительная память модели памяти Java приветствуется для просмотра:Глубокое понимание модели памяти Java, Написание очень подробное, рекомендуется прочитать несколько раз! ! !
Эта функция необходима в синглтоне реализации блокировки с двойной проверкой! ! !
моделирование
Фактически, благодаря приведенному выше анализу содержание, связанное с этой темой, было упомянуто и на него был дан ответ.
Хотя вы знаете причину, это непростая задача для моделирования!, давайте смоделируем эффект:
public class ThreadSafeCache {
int result;
public int getResult() {
return result;
}
public synchronized void setResult(int result) {
this.result = result;
}
public static void main(String[] args) {
ThreadSafeCache threadSafeCache = new ThreadSafeCache();
for (int i = 0; i < 8; i++) {
new Thread(() -> {
int x = 0;
while (threadSafeCache.getResult() < 100) {
x++;
}
System.out.println(x);
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadSafeCache.setResult(200);
}
}
Эффект:
Программа будет зависать здесь все время, указывая на то, что 200 модифицированных набором, метод get не виден! ! !
Добавьте ключевое слово volatile, чтобы наблюдать эффект
На самом деле ключевое слово synchronized в примере можно убрать и использовать только volatile.
Эффект:
Код заканчивается нормально скоро!
в заключении:Выполнять операции set и get одновременно с несколькими потоками,Поток вызывает метод set, и поток B не обязательно сможет увидеть это изменение! ! !, в приведенном выше коде, если в метод get добавлена синхронизация, она также видна или происходит доПравила блокировки монитора: разблокировка монитора происходит до последующей блокировки монитора., но volatile более легкий, чем синхронизированный, поэтому volatile используется непосредственно в этом примере. Однако для неатомарных операций i++ здесь все еще невозможно или синхронизировано.
Дополнительная память модели памяти Java приветствуется для просмотра:Глубокое понимание модели памяти Java, Написание очень подробное, рекомендуется прочитать несколько раз! ! !
Рекомендуется внимательно посмотретьРаспространенные сомнения и ловушки в Java, в ней много отличных вещей, если надо достатьполный ppt, вы можете ответить в диалоговом окне официального аккаунта: "PPT», чтобы получить полный файл!
Если вы чувствуете себя вознагражденным после прочтения, пожалуйста, поставьте лайк, подпишитесь и добавьте официальную учетную запись [Ingenuity Zero], чтобы узнать больше захватывающей истории! ! !