Scala 并行集合中的 foreach

foreach in Scala parallel collections

我用 Ammonite 评估了这段代码:

$ amm
Welcome to the Ammonite Repl 2.5.1 (Scala 2.13.8 Java 17.0.1)
@ import $ivy.`org.scala-lang.modules::scala-parallel-collections:1.0.4`
@ import scala.collection.parallel.CollectionConverters._
@ Seq(1,2).foreach { x => Thread sleep x*1000; println(s"Fin $x") };println("Fin") 
Fin 1
Fin 2
Fin

一切顺利。 如果我将 par 添加到并行化,那么它永远不会完成:

@ Seq(1,2).par.foreach { x => Thread sleep x*1000; println(s"Fin $x") };println("Fin")

这是一个错误吗? 使用 Scala 2.12,我得到了相同的行为。

你遇到这个问题是因为 Scala 的 lambda 编码的这个错误也会发生在 Scala REPL 中。

Scala 端的错误:https://github.com/scala/scala-parallel-collections/issues/34

相应的炸药错误报告在这里:https://github.com/com-lihaoyi/Ammonite/issues/556

您可以通过我知道的两种方式解决此问题。 第一种是将并行工作放在一个对象中,例如

  object work {
    def execute() = Seq(1, 2).foreach { x =>
      Thread.sleep(x * 1000); println(s"Fin $x")
    }; println("Fin")
  }
  work.execute

我相信 运行 带有 amm --class-based 的菊石也应该可以解决问题,但我现在无法对此进行测试。