Назад к вопросам
Middle
147
questionbank
Что такое атомарные типы данных и для чего они нужны?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Атомарные типы данных - это классы из пакета java.util.concurrent.atomic, предоставляющие примитивные типы и ссылки на объекты с атомарными (неделимыми) операциями. Они используются для безопасной работы с изменяемыми переменными в многопоточной среде без явного использования блокировок (например, с помощью synchronized).
Ключевые особенности:
- Атомарность: Гарантируют, что операция над переменной выполняется полностью или не выполняется вообще, предотвращая состояние гонки.
- Non-blocking: Большинство операций реализованы с использованием низкоуровневой инструкции Compare-And-Swap (CAS), которая не блокирует потоки.
- Производительность: В случаях высокого уровня конкуренции могут быть более производительными, чем блокировки.
- Volatile-like memory effects: Обладают свойствами видимости, схожими с ключевым словом
volatile.
Примеры популярных атомарных типов:
AtomicBooleanAtomicIntegerAtomicLongAtomicReferenceAtomicIntegerArrayAtomicLongArrayAtomicReferenceArray
Основные операции включают:
get(): Получить текущее значение.set(newValue): Установить новое значение.compareAndSet(expect, update): Атомарно установить значениеupdate, если текущее значение равноexpect.getAndIncrement(): Атомарно увеличить значение на 1 и вернуть предыдущее значение.incrementAndGet(): Атомарно увеличить значение на 1 и вернуть новое значение.
Необходимость атомарных типов возникает, когда требуется выполнять потокобезопасные операции над одиночными переменными без усложнения кода явными блокировками или риском возникновения взаимных блокировок.
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicExample {
public static void main(String[] args) throws InterruptedException {
AtomicInteger counter = new AtomicInteger(0); // Использование атомарного типа
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.incrementAndGet(); // Атомарное увеличение
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Final counter value: " + counter.get()); // Результат будет 2000
}
}