Логотип YeaHub

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

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

Тренажёр

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

Обучение

Навыки

Войти

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

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

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: thread safety, atomicity, increment, primitive int, race condition

Почему инкремент примитивного int не потокобезопасен?

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

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

Инкремент примитивного int (например, в Java) не является атомарной операцией на уровне процессора. Он состоит из трёх шагов: чтение значения из памяти, увеличение его на единицу и запись результата обратно. Если два потока одновременно выполняют эти шаги, они могут прочитать одно и то же исходное значение, независимо увеличить его и записать одинаковый результат, что приводит к потере одного инкремента. Для обеспечения потокобезопасности нужно использовать атомарные типы (AtomicInteger), синхронизацию (synchronized) или блокировки.

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

Инкремент переменной типа int кажется простой операцией, но в многопоточном контексте она раскладывается на несколько машинных инструкций. Это создаёт окно для состояния гонки (race condition), когда несколько потоков одновременно пытаются изменить одну и ту же переменную.

Почему операция не атомарна?

На большинстве архитектур операция i++ (где i — примитивный int) выполняется в три этапа:

  1. Чтение текущего значения переменной из памяти в регистр процессора.
  2. Увеличение этого значения на единицу (вычисление в регистре).
  3. Запись нового значения обратно в память.

Эти этапы не выполняются как одно неделимое действие (не атомарны). Поток может быть прерван операционной системой после любого шага.

Пример состояния гонки

Представьте, что два потока (A и B) одновременно инкрементируют одну переменную counter, начальное значение которой равно 0.

// Псевдокод выполнения
Поток A: читает counter (значение 0)
Поток B: читает counter (значение 0) // Чтение происходит до того, как A записал результат
Поток A: увеличивает прочитанное значение до 1
Поток B: увеличивает прочитанное значение до 1
Поток A: записывает 1 в counter
Поток B: записывает 1 в counter // Потерян один инкремент!
// Итоговое значение counter = 1, хотя ожидалось 2.

Как обеспечить потокобезопасность?

Для безопасного инкремента в многопоточной среде применяют:

  • Синхронизацию (ключевое слово synchronized в Java или мьютексы в других языках), которая гарантирует, что только один поток может выполнять критическую секцию кода в данный момент.
  • Атомарные классы (например, AtomicInteger в Java), которые предоставляют методы типа incrementAndGet(), реализованные с использованием низкоуровневых атомарных инструкций процессора (CAS — Compare-And-Swap).
  • Волатильные переменные (volatile) сами по себе не решают проблему инкремента, так как они обеспечивают только видимость изменений между потоками, но не атомарность составных операций.

Пример кода с AtomicInteger

import java.util.concurrent.atomic.AtomicInteger;

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

    public void increment() {
        counter.incrementAndGet(); // Атомарная операция
    }

    public int getValue() {
        return counter.get();
    }
}

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

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • Java

    Java

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

#thread safety

#atomicity

#increment

#primitive int

#race condition

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