Оптимистичная стратегия параллелизма — вращение на основе CAS

Java задняя часть глубокое обучение NLP
Оптимистичная стратегия параллелизма — вращение на основе CAS

У пессимиста и оптимиста совершенно разные способы ведения дел.Пессимистический взгляд на жизнь заключается в том, что я должен иметь 100% полный контроль, иначе я думаю, что с этим будут проблемы; в то время как оптимистический взгляд на жизнь - Вкл. наоборот, каким бы ни был конечный результат, он попытается сделать это первым, и в конце концов большое дело провалится. В этом разница между пессимистическими блокировками и оптимистическими блокировками.Пессимистические блокировки будут блокировать весь объект как свой собственный перед выполнением операций.Оптимистические блокировки не приобретают блокировки и выполняют операции напрямую, а затем определяют, следует ли обновлять данные с помощью определенных методов обнаружения. В этом разделе мы подробно обсудим оптимистическую блокировку.

Синхронизированный мьютекс, использованный ранее, представляет собой пессимистическую блокировку. У него есть очевидный недостаток. Он блокируется независимо от наличия конкуренции за хранилище данных. По мере увеличения параллелизма и при относительно длительном времени блокировки его накладные расходы на производительность станут очень высокими. Большой. Есть ли способ исправить это? Ответ — оптимистичная блокировка, основанная на обнаружении конфликтов. В этом режиме больше нет так называемой концепции блокировки.Каждый поток непосредственно выполняет операцию первым.После завершения расчета он определяет, существует ли конкуренция за общие данные с другими потоками.Если нет, то пусть операция завершается успешно.Если существует соревнование по общим данным, тогда операция и обнаружение могут непрерывно повторяться до тех пор, пока они не будут успешными, что называется вращением CAS.

Основным алгоритмом оптимистической блокировки является CAS (Сравнение и замена), который включает три операнда: значение в памяти, ожидаемое значение и новое значение. Измените значение памяти на новое значение тогда и только тогда, когда ожидаемое значение и значение памяти равны. Логика этой обработки заключается в том, чтобы сначала проверить, является ли значение определенного фрагмента памяти таким же, как когда я его читал ранее, если оно отличается, это означает, что значение памяти было изменено другими потоками в течение периода, и эта операция отбрасывается, иначе это означает, что других в течение периода нет.Потоки оперируют этим значением памяти и могут устанавливать новые значения в этот блок памяти. Как показано на рисунке, два потока могут работать с определенной памятью примерно в одно и то же время.Поток 2 сначала считывает определенное значение памяти как ожидаемое значение.При выполнении где-то поток 2 решает установить новое значение в блок памяти. Если поток 1 находится здесь Если блок памяти изменяется в течение периода, это может быть обнаружено CAS.Если обнаружение не вызывает проблем, второй поток присвоит новое значение блоку памяти.

Вы можете найти вопрос, сравните и обменяйтесь, там буквально две операции, не говоря уже о том, что собственно CAS может иметь больше инструкций выполнения, они атомарны? Если он неатомарный, как гарантировать проблемы, вызванные параллелизмом во время работы CAS? Нужно ли мне использовать мьютекс, упомянутый в предыдущем разделе, чтобы обеспечить его атомарную работу? CAS определенно является атомарным, иначе его нельзя использовать в параллелизме, но эта атомарность гарантируется реализацией аппаратных инструкций ЦП, то есть использованием JNI для вызова нативных методов для вызова инструкций аппаратного уровня, написанных на C++, предоставленных в jdk. класс выполняет эти операции. Кроме того, вы можете подумать, что CAS достигает атомарности за счет блокировок мьютексов, чего можно добиться, но бессмысленно обеспечивать атомарность таким образом. Следующий псевдокод углубляет понимание CAS:

public class AtomicInt {
    private volatile int value; 
    public final int get() {
        return value;
    }
	
	public final int getAndIncrement() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }
    
    public final boolean compareAndSet(int expect, int update) {
		Unsafe类提供的硬件级别的compareAndSwapInt方法;
    }
}

Наиболее важным методом является метод getAndIncrement, который реализует вращение на основе CAS. Теперь мы поняли оптимистическую блокировку и механизмы, связанные с CAS.Оптимистическая блокировка позволяет избежать явления пессимистической блокировки эксклюзивных объектов, а также улучшает производительность параллелизма, но также имеет недостатки:

  1. Блокировки просмотра могут гарантировать только атомарные операции над общей переменной. Как и в приведенном выше примере, во время процесса вращения может быть гарантирована только атомарность переменной значения.В это время, если есть одна или несколько переменных, оптимистическая блокировка станет неэффективной, но блокировку взаимного исключения можно легко решить, независимо от количества объектов и размера частиц объекта.
  2. Вращение в течение длительного времени может привести к большим накладным расходам. Если CAS долго не работает и продолжает крутиться, это принесет много накладных расходов на ЦП.
  3. проблема с АБА. Основная идея CAS состоит в том, чтобы судить о том, было ли изменено значение памяти, сравнивая, совпадает ли значение памяти с ожидаемым значением, но логика этого суждения не является строгой.Если значение памяти изначально было A, то он был изменен потоком на B и, наконец, изменен на Если возвращается A, CAS считает, что значение памяти не изменилось, но на самом деле оно было изменено другими потоками.Эта ситуация оказывает большое влияние на результаты работы сценариев которые зависят от значений процесса. Решение состоит в том, чтобы ввести номер версии и увеличивать номер версии на единицу при каждом обновлении переменной.

Оптимистическая блокировка является усовершенствованием пессимистической блокировки.Хотя у нее тоже есть недостатки, она действительно стала основным средством повышения параллельной производительности, а параллельные пакеты в jdk также активно используют оптимистическую блокировку на основе CAS.

------------- Рекомендуем прочитать ------------

Резюме моей статьи за 2017 год — машинное обучение

Краткое изложение моих статей за 2017 год — Java и промежуточное ПО

Резюме моих статей 2017 года — глубокое обучение

Краткое изложение моих статей за 2017 год — исходный код JDK

Резюме моей статьи за 2017 год — обработка естественного языка

Резюме моих статей 2017 года — Java Concurrency


Поговори со мной, задай мне вопросы:

这里写图片描述

Меню официальной учетной записи было разделено на «распределенное», «машинное обучение», «глубокое обучение», «НЛП», «глубина Java», «ядро параллелизма Java», «исходный код JDK», «ядро Tomcat», и т.д. Там может быть один стиль, чтобы удовлетворить ваш аппетит.

Зачем писать «Анализ проектирования ядра Tomcat»

Добро пожаловать, чтобы следовать:

这里写图片描述