並行集合是否打算做副作用操作?如果是這樣,你如何避免競爭條件? 例如:如何避免使用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