首页 文章

为什么这个Scala actor代码需要阻塞才能工作?

提问于
浏览
0

对于练习面试,我的朋友让我在规定的时间内与Scala演员实施合并排序 .

代码最终看起来像这样:

https://dl.dropboxusercontent.com/u/214507961/MergeActor.scala

基本上,应用程序将这样开始:

import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
import akka.actor.ActorSystem
import akka.actor.{ActorRef, Props}

def main(args: Array[String]): Unit = {

    val system = ActorSystem("CrappyActor1")

    implicit val timeout = Timeout(2.second)
    implicit val ec = system.dispatcher

    val firstActor: ActorRef = system.actorOf(Props[SortActor])
    val result = firstActor ? UnsortedList(List(1,3,2,4,-1))
    result.onSuccess {
      case SortedList(element) => Print.line("" + element.toString)
      case _ => Print.asrt(false, "Only a Sorted list was supposed to arrive.")
    }
    result.onFailure {
      case _ => Print.asrt(false, "Failure.")
    }
    system.shutdown()
}

^将创建第一个actor并传递未排序的数字列表 . 它将收到此列表,如果列表的长度大于2,它将分成列表的一半,将每一半分配给一个新的子actor .

如果列表只有1个或2个元素,则列表将被排序并发送回发送方/父级actor,直到返回完全排序的列表 .

问题是,在第62行的“MergeActor.scala”中,我需要添加:

Thread.sleep(5000) // This keeps the sender in existence.

^或者合并排序没有完成 . 为什么这种睡眠是必要的?你会怎么做?

*** Update ***

在“system.shutdown()”之前的“main”末尾添加“Thread.sleep(10000)”不起作用 . 在“MergeActor.scala”中注释掉“Thread.sleep(5000)”会导致“main”以“result.onFailure”结尾 .

"Failure: akka.pattern.AskTimeoutException: Ask timed out on [Actor[akka://CrappyActor1/user/$a#-1508387879]] after [2000 ms]" in thread CrappyActor1-akka.actor.default-dispatcher-3:

如果没有“Thread.sleep(5000)”,结果将在两秒钟超时之前返回 .

另外,我在失败之前得到了这个错误:

[INFO] [03/04/2016 15:34:05.696] [CrappyActor1-akka.actor.default-dispatcher-3] [akka://CrappyActor1/deadLetters] Message [mergeactors.MergeActor$SortedList] from Actor[akka://CrappyActor1/user/$a/$b#1429046332] to Actor[akka://CrappyActor1/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

1 回答

  • 1

    可能的原因可能是程序在结果返回之前退出 .

    你必须记住,即使在antoher线程或actor中有一些工作, Main 退出程序结束时所有执行都是分离的 .

    对于初学者,我建议只使用一个 concurrency model 而不要将 ActorsFutures 混合使用 . 当使用 ask? -pattern时会发生这种情况 .

    通过这种方式,您现在还必须考虑到可能的超时 .

    更新:回答扩展问题

    您描述的问题未连接到 actors ,而是连接到Scala Futures . 在这里,您将获得基本文档和用法示例:http://docs.scala-lang.org/overviews/core/futures.html .

    尝试

    Await.result(result, Duration.Inf)
    

相关问题