Что такое атомарные классы?
Атомарные классы в Java — это специальные классы из пакета java.util.concurrent.atomic, которые обеспечивают потокобезопасные операции над переменными без использования блокировок (synchronized). Они обеспечивают атомарность — то есть операции, которые выполняются целиком и не могут быть прерваны другим потоком.
🔍 Зачем нужны атомарные классы
В многопоточной среде, если несколько потоков обращаются к одной переменной, то простые операции (например, x++) не являются атомарными:
counter++; // не атомарно: читается значение, увеличивается, записывается обратно
→ Может возникнуть race condition — часть инкрементов будет потеряна.
Атомарные классы решают эту проблему без synchronized, с помощью низкоуровневых операций процессора (например, CAS — compare-and-swap).
Основные атомарные классы
Класс | Назначение |
---|---|
AtomicInteger | Атомарная целочисленная переменная (int) |
--- | --- |
AtomicLong | Атомарная переменная типа long |
--- | --- |
AtomicBoolean | Атомарное булево значение |
--- | --- |
AtomicReference<T> | Атомарная ссылка на объект |
--- | --- |
AtomicIntegerArray | Массив AtomicInteger |
--- | --- |
AtomicLongArray | Массив AtomicLong |
--- | --- |
AtomicReferenceArray<T> | Массив атомарных ссылок |
--- | --- |
Пример с AtomicInteger
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet(); // атомарное увеличение
}
public int get() {
return count.get(); // безопасное получение значения
}
}
→ Этот класс будет работать корректно в многопоточности, даже без synchronized.
📌 Основные методы
Для AtomicInteger (аналогично у других):
-
get() — получить текущее значение.
-
set(value) — задать новое значение.
-
incrementAndGet() — увеличить на 1 и вернуть новое значение.
-
getAndIncrement() — вернуть текущее значение и потом увеличить.
-
addAndGet(n) — прибавить n и вернуть результат.
-
compareAndSet(expected, new) — атомарно установить новое значение, если текущее равно expected.
AtomicInteger ai = new AtomicInteger(5);
ai.compareAndSet(5, 10); // если значение было 5, то становится 10
⚙️ Как это работает: CAS (compare-and-swap)
-
Поток читает текущее значение переменной.
-
Сравнивает его с ожидаемым (expected).
-
Если значение не изменилось с момента чтения, оно заменяется на новое.
-
Иначе — операция повторяется.
Этот механизм очень быстрый, потому что не требует захвата блокировки и может масштабироваться на многих ядрах.
🚫 Когда атомарные классы не подходят
-
Когда операция зависит от нескольких переменных одновременно — атомарность уже не гарантируется.
-
Когда требуется гибкое управление блокировками, лучше использовать ReentrantLock.
-
В сложных алгоритмах и структурах (например, списках) лучше использовать коллекции из java.util.concurrent.
✅ Преимущества
-
Потокобезопасность без использования synchronized.
-
Очень высокая производительность.
-
Упрощают код в простых случаях (инкремент счётчиков, флагов и т. д.).
🧠 Итого
Особенность | Атомарные классы |
---|---|
Потокобезопасны | ✅ Да, без synchronized |
--- | --- |
Используют CAS | ✅ Да |
--- | --- |
Основа | AtomicInteger, AtomicBoolean и др. |
--- | --- |
Подходят для | Счётчиков, флагов, ссылок |
--- | --- |
Не подходят для | Сложных зависимостей между переменными |
--- | --- |
Атомарные классы — это лёгкий, эффективный и надёжный способ обеспечить безопасность данных при параллельном доступе, особенно когда требуется высокая производительность без тяжёлой синхронизации.