The parallel case does not work because you do not use mutable variables, therefore you do not ensure the visibility of your records and because you have several threads that perform the following actions:
- read
sum
into register - add
sum
to the register - write updated value to memory
If 2 threads perform the first step one by one, and then proceed to complete the remaining steps above in any order, they will eventually overwrite one of the updates.
- Use the
@volatile
annotation to make sum
visible when doing something like this. See here . - Even with
@volatile
due to the non-atomic nature of the increment, you will lose some increments. You should use AtomicInteger
and their incrementAndGet
. - Although using atomic counters ensures correctness, shared variables hinder performance here - your shared variable is now a performance bottleneck because each thread is trying to atomically write to the same cache line. If you wrote this variable infrequently, it will not be a problem, but since you do it at each iteration, there will be no acceleration - in fact, due to the transfer of rights to the cache line between processors, it will probably be slower.
So, as Daniel suggested, use reduce
for this.
source share