Оптимистический замок и пессимистический замок необходимы для интервью

интервью Java база данных алгоритм

Рекомендуемое чтение:

Как продолжать расти в технологиях

Основные основы Linux для бэкэнд-программистов

Основы серверной части — универсальный свод знаний о передаче данных (RPC, очередь сообщений)

Что такое пессимистическая блокировка и оптимистичная блокировка

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

пессимистический замок

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

оптимистическая блокировка

Всегда предполагайте наилучшую ситуацию.Каждый раз, когда вы идете за данными, вы думаете, что другие не будут их изменять, поэтому они не будут заблокированы.Однако, когда вы обновляете их, вы будете судить, обновляли ли другие данные в течение этого периода Вы можете использовать механизм номера версии и реализацию алгоритма CAS.Оптимистическая блокировка подходит для типов приложений с множественным чтением, что может повысить пропускную способность., например, база данных предоставляет что-то вродемеханизм write_condition, по сути, предусмотрена оптимистическая блокировка. на Явеjava.util.concurrent.atomicКласс атомарной переменной в пакете — это реализация, использующая оптимистическую блокировку.CASосуществленный.

Два сценария использования блокировки

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

Две распространенные реализации оптимистической блокировки

Оптимистическая блокировка обычно реализуется с использованием механизма номера версии или алгоритма CAS.

1. Механизм номера версии

Как правило, в таблицу данных добавляется поле версии номера версии данных, указывающее, сколько раз данные были изменены.При изменении данных значение версии увеличивается на единицу. Когда поток A хочет обновить значение данных, он также считывает значение версии при чтении данных.При отправке обновления, если только что прочитанное значение версии равно значению версии в текущей базе данных, оно будет обновлено, в противном случае повторите попытку. Операция обновления до тех пор, пока обновление не будет успешным.

Возьмем простой пример:Предположим, что в таблице сведений об учетной записи в базе данных есть поле версии, текущее значение которого равно 1, а поле текущего баланса учетной записи (balance) равно $100.

  1. Теперь оператор А считывает его ( версия = 1 ) и вычитает 50 долларов из баланса своего счета ( 100-50 долларов ).
  2. Во время работы оператора A оператор B также считывает эту информацию о пользователе ( version=1 ) и вычитает 20 долларов (100-20 долларов) из баланса своего счета.
  3. Оператор А завершает работу по модификации, увеличивает номер версии данных на единицу ( версия = 2 ) и отправляет его в базу данных для обновления вместе с балансом после вычета учетной записи ( баланс = $ 50 ), В это время, начиная с представленной версии данных больше, чем текущая версия записи базы данных, данные удаляются. Обновить, версия записи базы данных обновляется до 2.
  4. Оператор B завершает операцию, а также увеличивает номер версии на единицу (version=2) и пытается отправить данные в базу данных (balance=80$), но в это время при сравнении версий записей в базе обнаруживается, что данные номер версии, отправленный оператором B, равен 2, текущая версия записи базы данных также равна 2, что не удовлетворяет оптимистичной стратегии блокировки «представленная версия должна быть больше, чем текущая версия записи для выполнения обновления». Поэтому , представление оператора B отклоняется.

Таким образом, исключается возможность перезаписи оператором B результата операции оператора A результатом модификации старых данных на основе версии=1.

2. Алгоритм CAS

которыйсравнить и поменять местами, известныйбезблокировочный алгоритм. Программирование без блокировок, то есть для достижения переменной синхронизации между несколькими потоками без использования блокировок, то есть для достижения переменной синхронизации без блокировки потоков, поэтому его также называют неблокирующей синхронизацией (Non-blocking Synchronization).CAS-алгоритмвключает три операнда

  • Значение памяти V, которое необходимо прочитать и записать
  • значение для сравнения A
  • новое значение B для записи

CAS атомарно обновляет значение V новым значением B тогда и только тогда, когда значение V равно A, в противном случае ничего не делается (сравнение и замена — атомарная операция). Обычнооперация отжима,Сейчаспродолжайте повторять попытку.

Недостатки оптимистической блокировки

Проблема ABA — распространенная проблема с оптимистичной блокировкой.

1 АВА-проблема

Если переменная V является значением A при первом чтении и проверяется, что она по-прежнему является значением A, когда она готова к присвоению, можем ли мы доказать, что ее значение не было изменено другими потоками? Очевидно, что нет, потому что за это время его значение может измениться на другие значения, а затем снова измениться на A, и операция CAS примет его за то, что оно никогда не изменялось. Эта проблема известна как операция CASПроблема "АБА".

JDK 1.5 и вышеAtomicStampedReference 类обеспечивает эту возможность, в которойcompareAndSet 方法То есть сначала проверить, равна ли текущая ссылка ожидаемой ссылке, и равен ли текущий флаг ожидаемому флагу, и если все равны, атомарно установить ссылку и значение флага на заданное обновленное значение.

2 Длительное время цикла и высокие накладные расходы

Spin CAS (то есть при неудаче будет выполняться в цикле до тех пор, пока не получится), при длительной неудаче принесет очень большие накладные расходы на выполнение CPU.Если JVM может поддерживать инструкцию паузы, предоставляемую процессором, эффективность будет в определенной степени повышена.Инструкция паузы имеет две функции.Во-первых, она может задерживать инструкцию выполнения конвейера (de-pipeline), так что ЦП не потреблять слишком много ресурсов исполнения.Время задержки зависит от конкретной версии реализации, на некоторых процессорах время задержки равно нулю. Во-вторых, он может избежать очистки конвейера ЦП, вызванной нарушением порядка памяти (нарушением порядка памяти) при выходе из цикла, тем самым повышая эффективность выполнения ЦП.

3 Атомарные операции, которые могут гарантировать только общую переменную

CAS действителен только для одной общей переменной и не действует, когда операция охватывает несколько общих переменных. Но начиная с JDK 1.5 при условииAtomicReference类Чтобы обеспечить атомарность между ссылочными объектами, вы можете поместить несколько переменных в один объект для операций CAS, поэтому мы можем использовать блокировки или использоватьAtomicReference类Объедините несколько общих переменных в одну общую переменную для работы.

Сценарии использования CAS и синхронизированного

Короче говоря, CAS подходит для того, чтобы писать меньше (многократные сценарии чтения, как правило, меньше конфликтов), а синхронизированный подходит для того, чтобы писать больше (многократные сценарии записи, как правило, больше конфликтов).

  1. В случае меньшей конкуренции за ресурсы (легкий конфликт потоков) использование синхронизированных блокировок синхронизации для блокировки потоков и переключения пробуждения, а также переключения между пользовательским режимом и режимом ядра потребляют дополнительные ресурсы ЦП, в то время как CAS реализован на аппаратном уровне и не требует войти в ядро.Нет необходимости переключать потоки, а операции с меньшей вероятностью будут вращаться, поэтому может быть достигнута более высокая производительность.
  2. В случае серьезной конкуренции за ресурсы (серьезный конфликт потоков) вероятность раскручивания CAS будет относительно велика, что приводит к трате большего количества ресурсов ЦП и эффективности ниже, чем при синхронизации.

Дополнение: Ключевое слово synchronized в области параллельного программирования на Java всегда было ветераном, многие называли его давным-давно.«Тяжеловесный замок». Однако после JavaSE 1.6 он был в основном введен для снижения потребления производительности, вызванного получением и снятием блокировок.Блокировка смещенияиЛегкий замоки другиеРазличные оптимизацииПосле этого в некоторых случаях стало не так тяжело. Базовая реализация синхронизированного в основном опирается наLock-FreeОчередь, основная идеяблокировка после отжима,Продолжать борьбу за блокировки после переключения конкуренции,Слегка жертвует честностью, но получает высокую пропускную способность. В случае меньшего количества конфликтов потоков можно получить производительность, аналогичную CAS, в случае серьезных конфликтов потоков производительность намного выше, чем у CAS.

Если вы считаете, что моя статья вам полезна, обратите внимание на мой паблик в WeChat: "Руководство по прохождению собеседования на Java"(Теплый общедоступный аккаунт WeChat, никакой рекламы, чистый обмен технологиями, с нетерпением жду прогресса вместе с вами~~~ настаивайте на оригинальности, делитесь красивыми текстами и делитесь различными учебными ресурсами Java.)