我创建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")
}
答案 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