Параллельный регистр не работает, потому что вы не используете изменчивые переменные, следовательно, не гарантируете видимость ваших записей и потому что у вас есть несколько потоков, которые делают следующее:
- читать
sum
в регистр
- добавить в регистр со значением
sum
- записать обновленное значение обратно в память
Если 2 потока выполнят шаг 1 сначала один за другим, а затем перейдут к выполнению остальных шагов, описанных выше, в любом порядке, они перезапишут одно из обновлений.
- Используйте аннотацию
@volatile
, чтобы обеспечить видимость sum
при выполнении чего-либо подобного. См. здесь .
- Даже с
@volatile
из-за неатомарности приращения вы потеряете некоторые приращения. Вы должны использовать AtomicInteger
s и их incrementAndGet
.
- Хотя использование атомарных счетчиков гарантирует правильность, наличие общих переменных сильно снижает производительность - ваша общая переменная теперь является узким местом производительности, потому что каждый поток будет пытаться атомарно записать в одну и ту же строку кэша. Если вы пишете в эту переменную нечасто, это не будет проблемой, но, поскольку вы делаете это на каждой итерации, здесь не будет никакого ускорения - фактически, из-за передачи владения строкой кэша между процессорами, это, вероятно, будет медленнее .
Итак, как предложил Даниил, используйте для этого reduce
.