Проблема: операция `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.
Почему ещё: вы используете `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.