并行集合是否打算进行副作用操作?如果是这样,你怎么能避免竞争条件? 例如:
var sum=0
(1 to 10000).foreach(n=>sum+=n); println(sum)
50005000
没问题。 但如果尝试并行化,竞争条件就会发生:
var sum=0
(1 to 10000).par.foreach(n=>sum+=n);println(sum)
49980037
答案 0 :(得分:17)
快速回答:不要这样做。并行代码应该是 parallel ,而不是并发。
更好的回答:
val sum = (1 to 10000).par.reduce(_+_) // depends on commutativity and associativity
另见aggregate
。
答案 1 :(得分:4)
并行情况不起作用,因为您不使用volatile变量,因此无法确保写入的可见性,并且因为您有多个线程执行以下操作:
sum
读入注册sum
值如果2个线程先依次执行第1步,然后按任何顺序继续执行上述其余步骤,则最终会覆盖其中一个更新。
@volatile
注释确保在执行此类操作时sum
的可见性。见here。@volatile
,由于增量的非原子性,您将失去一些增量。您应该使用AtomicInteger
和他们的incrementAndGet
。所以,正如丹尼尔建议的那样 - 使用reduce
。