【问题标题】:Scala Parallel Print Hanging the consoleScala Parallel Print 挂起控制台
【发布时间】:2017-02-10 04:04:01
【问题描述】:

我是这个 Scala 世界的新手,我正在尝试书中的一些练习。所以,我有一个以顺序和并行方式打印向量的示例。前者完美运行,后者挂起控制台。

代码

val v = Vector.range(0, 10)
v.foreach(println)

代码输出

0123456789

但如果我使用相同的代码,但不使用 foarch,而是使用 par,它会冻结控制台

val v = Vector.range(0,10)
v.par.foreach(println)

我使用的书说输出应该是这样的:

5678901234    

但它挂起并且程序永远不会完成。

谁能解释一下为什么?

【问题讨论】:

  • 这并不明显,但这是由于从静态初始化程序启动线程所致。有一个SO,我会尽力找到它。 issues.scala-lang.org/browse/SI-8119stackoverflow.com/questions/15176199/… 该票建议了解决方法。最简单的方法是本地化,{ x.par }
  • 我用 scala 2.12.1 测试过 - 控制台挂了。使用 scala 2.11.8 可以正常工作。
  • 谢谢大家的回答,我只是好奇原因。我没有在当前项目中使用它。
  • 我通过使用scala -Yrepl-class-based(根据this comment)启动repl 来实现此功能,但是我尝试的所有其他方法(包括将命令的各个部分包装在大括号中)都不起作用。跨度>
  • 进一步的证据:这在默认 repl 中有效:class X { Vector.range(0,10). par.foreach(print) } ; new X,但这不适用于 object X { Vector.range(0,10). par.foreach(print) } ; X

标签: scala foreach par


【解决方案1】:

最好发布整个被吊死的程序。

我刚刚用 scala 2.12.8 和 jvm 1.8.0_161 测试过:

object MainClassss {
  def main(args: Array[String]): Unit = {
    val v = Vector.range(0,10)
    (0 to 999999).foreach(_ => v.par.foreach(println))
  }
}

程序执行良好,输出良好,没有挂起。

如果您的程序重现了上述问题,您需要通过以下方式进行线程转储:

$ jstack <PID>

其中 PID 是进程 ID。

或者你可以通过jvisualvm jvm 工具来获取。

如果程序有一些代码阻止它执行,你可以分析为什么你的程序由于捕获的线程转储而挂起。

【讨论】:

    猜你喜欢
    • 2014-04-22
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 2014-09-21
    • 1970-01-01
    • 2012-11-07
    • 2015-10-13
    相关资源
    最近更新 更多