В многопоточном Java-коде есть два способа изменить общую переменную.



Способ 1: `synchronized` (Пессимистичный)

В процессоре эта «очередь» сжигает ресурсы: потоки засыпают и просыпаются, ядро постоянно переключается между ними.

Способ 2: CAS — Compare-And-Swap (Оптимистичны
й)

Работает по принципу «попробуй и проверь».

Процесс выглядит так:
1. Поток читает текущее значение из памяти
(например, видит число 5).
2. Поток вычисляет новое значение
(5 + 1 = 6).
3. Поток дает команду процессору:
«Замени это значение на 6, но только если оно всё еще равно 5. Если за то время, пока я считал, кто-то уже успел записать туда другое число — не делай ничего и сообщи мне об ошибке».

Если запись удалась — отлично.
Если нет (кто-то вмешался) — поток просто повторяет всю операцию заново с новым значением. Это происходит очень быстро прямо внутри ядра CPU, обращения к операционной системе не требуется.

Как это выглядит
в коде

Вам не нужно писать логику цикла вручную. Для этого есть классы из пакета `java.util.concurrent.atomic`.

// Обычная переменная (небезопасна)
private int counter = 0;

// Атомарная переменная (использует CAS под капотом)
private final AtomicInteger atomicCounter = new AtomicInteger(0);

public void increment() {
// Внутри этой строки скрыт цикл "прочитал-попробовал-снова"
atomicCounter.incrementAndGet( );
}

Метод compareAndSet(int expect, int update) делает ровно то, что описано выше:
* expect — то, что мы прочитали мгновение назад.
* update — то, что хотим положить взамен.
* Возвращает true, если удалось заменить, или false, если значение в памяти успело измениться.

Где у CAS проблемы
(ABA Problem)

У оптимистичного подхода есть один изъян. Допустим, в переменной лежит объект A.
1. Поток-1 прочитал адрес объекта A.
2. Произошла пауза. Другой поток удалил A.
3. Система выделила ту же самую ячейку памяти под совершенно новый объект и снова назвала его A.
4. Вернулся Поток-1. Он делает проверку: «Там все еще A? Да. Пишу свое».
Просмотры: 88
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти