为什么 ListBuffer.par foreach 不起作用?
Why ListBuffer.par foreach does not work?
在 Scala 程序中,我有:
var steps : ListBuffer[Step] = new ListBuffer[Step]
var newsteps : ListBuffer[Step] = new ListBuffer[Step]
// why par is not working ?
steps.foreach(step => newsteps ++= step.execute())
这行得通。 step
仅对内部状态进行操作,所有数据都是不可变的。然而,当我添加 par
来并行化工作时:
steps.par.foreach(step => newsteps ++= step.execute())
结果不可预测。我在这里遗漏了什么吗?
ListBuffer
不是线程安全的,您正在从多个线程追加它 (newsteps++=
)(这就是您在并行收集上调用 foreach
时发生的情况)。
此外,Scala 不鼓励将副作用与并行操作混合:
Given the concurrent execution semantics of the parallel collections framework, operations performed on a collection which cause side-effects should generally be avoided, in order to maintain determinism.
http://docs.scala-lang.org/overviews/parallel-collections/overview.html
在 Scala 程序中,我有:
var steps : ListBuffer[Step] = new ListBuffer[Step]
var newsteps : ListBuffer[Step] = new ListBuffer[Step]
// why par is not working ?
steps.foreach(step => newsteps ++= step.execute())
这行得通。 step
仅对内部状态进行操作,所有数据都是不可变的。然而,当我添加 par
来并行化工作时:
steps.par.foreach(step => newsteps ++= step.execute())
结果不可预测。我在这里遗漏了什么吗?
ListBuffer
不是线程安全的,您正在从多个线程追加它 (newsteps++=
)(这就是您在并行收集上调用 foreach
时发生的情况)。
此外,Scala 不鼓励将副作用与并行操作混合:
Given the concurrent execution semantics of the parallel collections framework, operations performed on a collection which cause side-effects should generally be avoided, in order to maintain determinism.
http://docs.scala-lang.org/overviews/parallel-collections/overview.html