Giuliano
Giuliano

Reputation: 133

how to avoid race conditions with scala parallel collections

Are parallel collections intended to do operations with side effects? If so, how can you avoid race conditions? For example:

var sum=0
(1 to 10000).foreach(n=>sum+=n); println(sum)

50005000

no problem with this. But if try to parallelize, race conditions happen:

var sum=0
(1 to 10000).par.foreach(n=>sum+=n);println(sum)

49980037

Upvotes: 7

Views: 800

Answers (2)

axel22
axel22

Reputation: 32335

Parallel case doesn't work because you don't use volatile variables hence not ensuring visibility of your writes and because you have multiple threads that do the following:

  1. read sum into a register
  2. add to the register with the sum value
  3. write the updated value back to memory

If 2 threads do step 1 first one after the other and then proceed to do the rest of the steps above in any order, they will end up overwriting one of the updates.

  1. Use @volatile annotation to ensure visibility of sum when doing something like this. See here.
  2. Even with @volatile, due to the non-atomicity of the increment you will be losing some increments. You should use AtomicIntegers and their incrementAndGet.
  3. Although using atomic counters will ensure correctness, having shared variables here hinders performance greatly - your shared variable is now a performance bottleneck because every thread will try to atomically write to the same cache line. If you wrote to this variable infrequently, it wouldn't be a problem, but since you do it in every iteration, there will be no speedup here - in fact, due to cache-line ownership transfer between processors, it will probably be slower.

So, as Daniel suggested - use reduce for this.

Upvotes: 5

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297155

Quick answer: don't do that. Parallel code should be parallel, not concurrent.

Better answer:

val sum = (1 to 10000).par.reduce(_+_) // depends on commutativity and associativity

See also aggregate.

Upvotes: 18

Related Questions