我有以下代码:
actor {
loop {
react {
case SomeEvent =>
//I want to submit a piece of work to a queue and then send a response
//when that is finished. However, I don't want *this* actor to block
val params = "Some args"
val f: Future[Any] = myQueue.submitWork( params );
actor {
//await here
val response = f.get
publisher ! response
}
}
}
}
据我所知,外部actor不会阻塞f.get
,因为它实际上是由一个单独的actor(在SomeEvent
处理程序中创建的)执行的。
这是对的吗?
答案 0 :(得分:2)
是的,这是正确的。你的外部演员只会创建一个actor并暂停(等待它的下一条消息)。但是,要非常小心这种事情。内部actor在调度程序上自动启动,由线程处理。该线程将阻止在那个Future上(看起来像java.util.concurrent.Future给我)。如果你这样做了足够多次,你可能遇到饥饿问题,其中所有可用的线程都在期货上阻塞。一个actor基本上是一个工作队列,所以你应该使用那些语义。
以下是使用Scalaz actors library的代码版本。这个库比标准的Scala actor更简单易懂(源代码实际上是一页半)。它还会导致更多的代码:
actor {(e: SomeEvent) => promise { ... } to publisher }
此版本完全无阻塞。