为什么此代码不会终止

时间:2015-02-20 17:35:32

标签: scala

此代码:

object SpeedTest extends Application{

  val l = (1 to 50).toList.par

  println("par done")
  var counter = 0;

  for(e <- l){
      counter + 1
  }

  println("Finished")

}

永远不会终止。如果我删除counter + 1,它会终止。导致此代码挂起的原因是什么?计数增量中是否出现死锁?

更新1:

更新代码以使用main方法而不是扩展Application:

object SpeedTest {

  def main(args: Array[String]) {
    SpeedTest.doInPar
  }

  def doInPar = {
    val l = (1 to 50).toList.par

    println("par done")
    var counter = 0;

    for (e <- l) {
      counter + 1
    }

    println("Finished")

  }

}

这终止,因此可能延长应用程序会产生负面影响。

更新2:

我的设置:

Version: Kepler Service Release 2
Build id: 20140224-0627
Java version : 1.6
Scala version : 2.10.4

1 个答案:

答案 0 :(得分:0)

正如Ben Reich所说,这可能是一个REPL错误,我认为这是因为某种“递归死锁”而发生的错误。如果我将计数器变量移动到另一个对象中,我可以使用它,如下所示:

object Somes{ var counter = 0}

object SpeedTest{
  val l = (1 to 7).toList.par

  println("par done")
  var counter = 0;
  for(e <- l){
      println("loop start for " + e)
      Somes.counter + 1
      println("loop done for " + e)
  }
  println("Finished")
}

如果您开始使用SpeedTest.counter,您会看到它运行到counter访问和停止。我的猜测是该对象尚未完全完成,因此尝试访问内部变量死锁,因为它仍然在构建自己。

事实上,通过在for循环分配中添加lazy val f = ...并在初始构建后引用它来加强这一点。