并行集合是否打算做副作用操作?如果是这样,你如何避免竞争条件? 例如:如何避免使用scala并行集合的竞争条件
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
并行集合是否打算做副作用操作?如果是这样,你如何避免竞争条件? 例如:如何避免使用scala并行集合的竞争条件
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
快速回答:不要这样做。并行代码应该是并行,不是并发的。
更好的答案:
val sum = (1 to 10000).par.reduce(_+_) // depends on commutativity and associativity
也aggregate
见。
并行的情况下不工作,因为你不使用volatile变量,因此不能保证你写的知名度,因为你有多个线程执行以下操作:
sum
到寄存器sum
值如果2个线程做步骤1第一O然后继续以任何顺序完成上述其余步骤,它们将最终覆盖其中一个更新。
@volatile
注释来确保sum
在执行此类操作时的可见性。请参阅here。@volatile
,由于增量的非原子性,您将会失去一些增量。您应该使用AtomicInteger
s和它们的incrementAndGet
。因此,正如丹尼尔所说 - 为此使用reduce
。
不,副作用不好。如果你没有状态,那就很难有竞争条件。 – PlexQ 2012-03-31 01:32:27