尽管我创造了10000个,但为什么演员不能完成所有工作?

时间:2016-10-29 05:51:05

标签: scala akka

我创建10000个演员并向每个演员发送消息,但似乎akka系统无法完成所有工作。 当我检查线程状态时,它们都在TIMED_WATIING

我的代码:

class Reciver extends Actor {
  val log = Logging(context.system, this)
  var num = 0

  def receive = {
    case a: Int => log.info(s"[${self.path}] receive $a, num is $num")
      Thread.sleep(2000)
      log.info(s"[${self.path}] processing $a, num is $num")
      num = a
  }
}

object ActorSyncOrAsync extends App {
  val system = ActorSystem("mysys")

  for (i <- 0 to 10000) {
    val actor = system.actorOf(Props[Reciver])
    actor ! i
  }
  println("main thread send request complete")
}

1 个答案:

答案 0 :(得分:4)

您应该删除Thread.sleep或(如果您使用默认线程池)将其包围:

scala.concurrent.blocking { 
  Thread.sleep(2000)
}

scala.concurrent.blocking标记计算具有托管阻塞,这意味着它告诉池计算不占用CPU资源但只是等待某些结果或超时。但是你应该be careful with this。因此,基本上,如果您使用Thread.sleep进行调试或仅模拟某些活动,此建议就有效 - 在生产代码中不应出现Thread.sleep(甚至被blocking包围)。

解释

当使用某个固定池时(包括fork-join,因为它不会从Thread.sleep阻塞的线程中窃取工作) - 只有POOL_SIZE线程(默认情况下它等于系统中的核心数) )用于计算。其他一切都将排队等候。

所以,让我们说4个核心,每个任务2秒,10000个任务 - 它需要2 * 10000/4 = 5000秒。

一般建议是在演员内部不阻止(包括Thread.sleep):Blocking needs careful management。如果您需要延迟某些操作,最好使用Scheduler(如@Lukasz所述):http://doc.akka.io/docs/akka/2.4.4/scala/scheduler.html