AtomicInteger
Целое число, которое можно безопасно менять из нескольких потоков без блокировок.
Доступно с: Java 1.5
Синтаксис
public class AtomicInteger extends NumberПримеры
Счётчик запросов из многих потоков:
void main() {
var requests = new AtomicInteger();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 1000; i++) {
executor.submit(requests::incrementAndGet);
}
}
IO.println(requests.get());
}Результат:
1000Основные операции:
void main() {
var n = new AtomicInteger(5);
IO.println(n.incrementAndGet());
IO.println(n.getAndAdd(10));
IO.println(n.updateAndGet(x -> x * 2));
IO.println(n.compareAndSet(32, 0) + " " + n.get());
}Результат:
6
6
32
true 0Примечания
incrementAndGet() возвращает новое значение, getAndIncrement() — старое. compareAndSet(expected, new) меняет значение, только если оно равно ожидаемому. Для long есть AtomicLong, а при очень частом обновлении из многих потоков — LongAdder.
См. также
- synchronized — Разрешает выполнять блок кода только одному потоку за раз.
- ConcurrentHashMap — Потокобезопасный словарь для одновременной работы из многих потоков.
- volatile — Помечает поле, изменения которого сразу видны всем потокам.
Вопросы и ответы по теме
В учебнике
- Синхронизация — Гонка данных в Java и как её избежать — synchronized-методы и блоки, атомарные классы AtomicInteger, ReentrantLock и общий объект блокировки.