Найдите проблему в многопоточном фрагменте Java: Integer counter = 0; Runnable r = () -> { for(int i=0;i

19 Мар в 11:58
15 +1
0
Ответы
1
Проблема: операция `counter++` не атомарна — фактически выполняется чтение значения, вычисление нового и присваивание (read-modify-write). При запуске 101010 потоков по 100010001000 итераций возникает гонка, поэтому результат может быть меньше ожидаемых 100001000010000.
Почему ещё: вы используете `Integer` (непримитивный, immutable) с автокоробкой — каждый `++` создаёт новый объект и переприсваивание не синхронизировано; `volatile` тоже не решит проблему, потому что не делает инкремент атомарным.
Как исправить (варианты, кратко):
- AtomicInteger (рекомендуется):
- Пример: `AtomicInteger counter = new AtomicInteger(000);`
- Внутри Runnable: `counter.incrementAndGet();` (атомарно).
- LongAdder (при высокой конкуренции — лучше масштабируется):
- Пример: `LongAdder counter = new LongAdder();`
- В Runnable: `counter.increment();`
- Итог: `counter.sum()`.
- Синхронизация:
- Общий замок: `synchronized(lock) { counter++; }` (если `counter` — примитивное поле или элемент массива).
- Или synchronized-метод/блок вокруг инкремента.
Вывод: замените `Integer counter = 0;` и `counter++` на атомарную операцию, например `AtomicInteger` или `LongAdder`, чтобы получить детерминированный итог 10×1000=1000010\times1000 = 1000010×1000=10000.
19 Мар в 12:06
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир