Scala对象构造函数中出现死锁,但相同的代码可在方法或类构造函数中工作

时间:2018-12-20 17:24:36

标签: scala concurrency deadlock future

我试图理解在类或对象方法中运行的代码与在对象构造函数中运行的代码之间的正确性。我想知道是否有人可以帮助我解释这种行为。

我正在运行以下MCVE示例代码:

  val names: Seq[String] = Seq("foo1", "bar1", "foo2", "bar2")
  var i=0
  names.grouped(2).toList.map { groupedNames => {
    i = i + 1
    println(s"[${i}] - [groupedNames=${groupedNames.size}=${groupedNames}]")
    val tasks: Seq[Future[Unit]] = for (name <- groupedNames) yield Future {
      println(s"[${i}] - [name=${name}]")
    }
    val aggregated: Future[Seq[Unit]] = Future.sequence(tasks)
    Await.result(aggregated, Duration.Inf)
  }}

当我在类构造函数,类方法或对象方法中运行它时,它将按预期工作。例如:

import scala.concurrent.duration._
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global

object bar {
  def foo = {
    val names: Seq[String] = Seq("foo1", "bar1", "foo2", "bar2")
    var i=0
    names.grouped(2).toList.map { groupedNames => {
      i = i + 1
      println(s"[${i}] - [groupedNames=${groupedNames.size}=${groupedNames}]")
      val tasks: Seq[Future[Unit]] = for (name <- groupedNames) yield Future {
        println(s"[${i}] - [name=${name}]")
      }
      val aggregated: Future[Seq[Unit]] = Future.sequence(tasks)
      Await.result(aggregated, Duration.Inf)
    }}
  }
}

object app extends App {
  println("Press any key to continue")
  scala.io.StdIn.readLine()
  bar.foo
  println("And again press any key to continue")
  scala.io.StdIn.readLine()
}

当我运行它时,我得到:

$> scala app
Press any key to continue

[1] - [groupedNames=2=List(foo1, bar1)]
[1] - [name=foo1]
[1] - [name=bar1]
[2] - [groupedNames=2=List(foo2, bar2)]
[2] - [name=foo2]
[2] - [name=bar2]
And again press any key to continue

这是线程图:

enter image description here

但是当我在bar对象构造函数(未包装在方法中)中运行它时,始终出现死锁:

import scala.concurrent.duration._
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global

object bar {
  //def foo = {
    val names: Seq[String] = Seq("foo1", "bar1", "foo2", "bar2")
    var i=0
    names.grouped(2).toList.map { groupedNames => {
      i = i + 1
      println(s"[${i}] - [groupedNames=${groupedNames.size}=${groupedNames}]")
      val tasks: Seq[Future[Unit]] = for (name <- groupedNames) yield Future {
        println(s"[${i}] - [name=${name}]")
      }
      val aggregated: Future[Seq[Unit]] = Future.sequence(tasks)
      Await.result(aggregated, Duration.Inf)
    }}
  //}
}

object app extends App {
  println("Press any key to continue")
  scala.io.StdIn.readLine()
  bar
  println("And again press any key to continue")
  scala.io.StdIn.readLine()
}

and run:
$> scala app
Press any key to continue

[1] - [groupedNames=2=List(foo1, bar1)]

在代码是对象构造函数的一部分时查看线程,主线程始终死锁:

运行1 code in object constructor 1 运行2 enter image description here

值得重复的是,我仅在对象构造函数中遇到此死锁。当我将相同的代码放入类构造函数或类方法的对象中时,不会出现死锁

0 个答案:

没有答案