對於一次實習求職面試,我的朋友要求我在規定的時間段內與Scala演員實施合併排序。爲什麼這個Scala actor代碼需要阻塞才能工作?
的代碼最終看上去像這樣:
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()
}
^第一男主角會被創建並傳遞的無序列表數字。它會收到這個清單,如果清單長度超過兩個,它將分成一半,每半個清單給一個新的兒童演員。
如果列表只包含1或2個元素,則列表將被排序併發送回發件人/父行動者,直到返回完全排序的列表。
的事情是,在「MergeActor.scala」上線62,我需要添加:
Thread.sleep(5000) // This keeps the sender in existence.
^或者合併排序沒有完成。爲什麼這個睡眠是必要的?你會怎麼做?
*更新*
添加 「了Thread.sleep(10000)」 在 「主」 年底前 「system.shutdown()」 沒有工作。在「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'.
我認爲合併是從屬線程執行。你必須讓主線程保持活動狀態,否則通常會結束工作,其他線程會在以後關閉。 – Rumoku
@rumoku我對阿卡一無所知。我所知道的是,如果我註釋掉「Thread.sleep(5000)」,我會在主線程中獲得「akka.pattern.AskTimeoutException」,這是創建父actor的線程。另外,我不認爲我正在進行任何合併 - 執行合併的線程在返回排序列表後自行排序「PoisonPill」本身。保持主線程不活動。 –