Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про Java: Java, AtomicInteger, concurrency, thread safety, atomic operations

Что такое AtomicInteger?

Вопрос проверяет понимание потокобезопасного класса AtomicInteger в Java, который используется для атомарных операций над целочисленными значениями в многопоточной среде.

Короткий ответ

AtomicInteger — это класс из пакета java.util.concurrent.atomic, который предоставляет целочисленное значение, операции над которым (инкремент, декремент, сложение) являются атомарными. Это означает, что эти операции выполняются как единое целое без вмешательства других потоков, что предотвращает состояние гонки. Он часто используется в качестве счётчика или для реализации неблокирующих алгоритмов. Внутри он использует низкоуровневые механизмы процессора (например, CAS — compare-and-swap) для обеспечения эффективной потокобезопасности.

Длинный ответ

AtomicInteger — это ключевой класс в Java для работы с многопоточностью, когда необходимо безопасно изменять целочисленное значение из нескольких потоков. В отличие от примитивного int или класса Integer, операции с AtomicInteger гарантируют атомарность, то есть они либо полностью выполняются, либо не выполняются вовсе, без промежуточных состояний, видимых другим потокам. Это устраняет необходимость в явной синхронизации с помощью ключевого слова synchronized для простых операций, что может повысить производительность в высококонкурентных сценариях.

Как это работает внутри?

В основе AtomicInteger лежит концепция сравнения с обменом (Compare-And-Swap, CAS). Метод compareAndSet сравнивает текущее значение с ожидаемым и, если они совпадают, устанавливает новое значение. Эта операция выполняется на уровне процессора как одна атомарная инструкция. Большинство других методов, таких как incrementAndGet(), используют CAS в цикле (часто называемом "spin loop" или "optimistic locking"), пока операция не завершится успешно.

Основные методы и применение

AtomicInteger часто применяется для:

  • Счётчиков (например, подсчёт количества выполненных задач).
  • Генерации уникальных последовательных идентификаторов.
  • Реализации неблокирующих структур данных (например, семафоров, барьеров).

Пример кода, демонстрирующий использование AtomicInteger как счётчика в многопоточной среде:

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AtomicExample {
    private static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        
        // Запускаем 100 задач, каждая увеличивает счётчик
        for (int i = 0; i < 100; i++) {
            executor.submit(() -> {
                // Атомарное увеличение на 1
                counter.incrementAndGet();
            });
        }
        
        executor.shutdown();
        // Ждём завершения всех задач
        while (!executor.isTerminated()) { }
        
        System.out.println("Final counter value: " + counter.get()); // Гарантированно 100
    }
}

В этом примере, даже если 10 потоков одновременно пытаются изменить counter, метод incrementAndGet() обеспечивает, что каждое увеличение будет учтено, и итоговое значение будет равно 100. Без AtomicInteger при использовании обычного int результат мог бы быть меньше из-за состояния гонки.

Сравнение с synchronized

Использование synchronized для защиты операции инкремента также обеспечивает корректность, но может привести к блокировкам и снижению производительности при высокой конкуренции. AtomicInteger, используя неблокирующие алгоритмы (CAS), часто работает быстрее в таких условиях, так как потоки не приостанавливаются, а активно "спинятся" в цикле, пока не добьются успеха.

Вывод: AtomicInteger стоит применять, когда вам нужен простой потокобезопасный счётчик или атомарные операции над целыми числами в многопоточном приложении, и вы хотите избежать накладных расходов на явную синхронизацию. Он особенно полезен в высоконагруженных системах, где важна производительность и масштабируемость.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Java

    Java

Ключевые слова

#Java

#AtomicInteger

#concurrency

#thread safety

#atomic operations

Подпишись на Java Developer в телеграм