РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1043 of 1163 menu

Метод compareAndSet

Метод compareAndSet класса AtomicInteger атомарно сравнивает текущее значение с ожидаемым. Если текущее значение равно ожидаемому, метод устанавливает новое значение и возвращает true. В противном случае значение не изменяется, а метод возвращает false. В первый параметр мы передаем ожидаемое значение (expected), во второй - новое значение (newValue).

Операция выполняется атомарно, то есть без промежуточных состояний, видимых другим потокам. Это делает метод основой для lock-free алгоритмов и неблокирующих структур данных.

Синтаксис

atomicInteger.compareAndSet(expectedValue, newValue)

Пример

Давайте создадим AtomicInteger со значением 10 и попробуем заменить его на 20, указав правильное ожидаемое значение:

import java.util.concurrent.atomic.AtomicInteger; public class Main { public static void main(String[] args) { AtomicInteger atomic = new AtomicInteger(10); boolean res = atomic.compareAndSet(10, 20); System.out.println(res); System.out.println(atomic.get()); } }

Результат выполнения кода:

true 20

Пример

А теперь укажем неверное ожидаемое значение. Текущее значение 10 не равно ожидаемому 5, поэтому замена не произойдет:

import java.util.concurrent.atomic.AtomicInteger; public class Main { public static void main(String[] args) { AtomicInteger atomic = new AtomicInteger(10); boolean res = atomic.compareAndSet(5, 20); System.out.println(res); System.out.println(atomic.get()); } }

Результат выполнения кода:

false 10

Пример

Метод compareAndSet часто используют в цикле для безопасного обновления значения без блокировок. Давайте увеличим значение на 1 с помощью CAS-цикла:

import java.util.concurrent.atomic.AtomicInteger; public class Main { public static void main(String[] args) { AtomicInteger atomic = new AtomicInteger(100); int current; int next; do { current = atomic.get(); next = current + 1; } while (!atomic.compareAndSet(current, next)); System.out.println(atomic.get()); } }

Результат выполнения кода:

101

Пример

Рассмотрим работу метода в двух потоках. Первый поток успешно меняет значение, а второй - нет, так как ожидаемое значение уже устарело:

import java.util.concurrent.atomic.AtomicInteger; public class Main { public static void main(String[] args) throws InterruptedException { AtomicInteger atomic = new AtomicInteger(1); Thread t1 = new Thread(() -> { boolean res = atomic.compareAndSet(1, 2); System.out.println("t1: " + res); }); Thread t2 = new Thread(() -> { boolean res = atomic.compareAndSet(1, 3); System.out.println("t2: " + res); }); t1.start(); t1.join(); t2.start(); t2.join(); System.out.println(atomic.get()); } }

Результат выполнения кода:

t1: true t2: false 2

Смотрите также

  • класс AtomicInteger,
    который хранит атомарное целое число
  • метод get,
    который возвращает текущее значение
  • метод set,
    который устанавливает новое значение
  • метод incrementAndGet,
    который атомарно увеличивает значение на единицу
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить