我在一台主机上启动两个远程actor,它们只是回显发送给它们的任何东西。然后我创建另一个actor,它向两个actor发送一些消息(使用!!),并保留一个List of Future对象来保存这些actor的回复。然后我遍历此List获取每个Future的结果。问题在于大多数时候某些期货永远不会回归,甚至认为该演员声称它已经发送了回复。问题是随机发生的,有时它会通过整个列表,但大多数时候它会在某个时刻陷入困境并无限期地挂起。
以下是一些在我的机器上产生问题的代码:
Sink.scala:
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.Exit
import scala.actors.remote.RemoteActor
import scala.actors.remote.RemoteActor._
object Sink {
def main(args: Array[String]): Unit = {
new RemoteSink("node03-0",43001).start()
new RemoteSink("node03-1",43001).start()
}
}
class RemoteSink(name: String, port: Int) extends Actor
{
def act() {
println(name+" starts")
trapExit=true
alive(port)
register(Symbol(name),self)
loop {
react {
case Exit(from,reason) =>{
exit()
}
case msg => reply{
println(name+" sending reply to: "+msg)
msg+" back at you from "+name
}
}
}
}
}
Source.scala:
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.remote.Node;
import scala.actors.remote.RemoteActor
import scala.actors.remote.RemoteActor._
object Source {
def main(args: Array[String]):Unit = {
val peer = Node("127.0.0.1", 43001)
val source = new RemoteSource(peer)
source.start()
}
}
class RemoteSource(peer: Node) extends Actor
{
def act() {
trapExit=true
alive(43001)
register(Symbol("source"),self)
val sinks = List(select(peer,Symbol("node03-0"))
,select(peer,Symbol("node03-1"))
)
sinks.foreach(link)
val futures = for(sink <- sinks; i <- 0 to 20) yield sink !! "hello "+i
futures.foreach( f => println(f()))
exit()
}
}
我做错了什么?
答案 0 :(得分:2)
我猜你的问题是由于这一行:
futures.foreach( f => println(f()))
在其中循环遍历所有期货并依次阻止每个期货,等待其结果。阻碍期货通常是一个坏主意,应该避免。您想要做的是指定一个动作,以便在未来的结果可用时执行 。试试这个:
futures.foreach(f => f.foreach(r => println(r)))
这是另一种说法,用于理解:
for (future <- futures; result <- future) { println(result) }
This blog entry是关于期货受阻以及monadic期货如何克服它的一个很好的入门读物。
答案 1 :(得分:0)
我也见过类似的情况。当线程内的代码抛出某些类型的异常并退出时,相应的future.get永远不会返回。可以尝试引发java.lang.Error与java.lang.NoSuchMethodError的异常。后者的相应未来永远不会回归。