5

我在一台主机上启动了两个远程参与者,它们只是回显发送给他们的任何内容。然后,我创建另一个参与者,它向两个参与者发送一些消息(使用 !! ),并保留一个未来对象列表,其中包含来自这些参与者的回复。然后我遍历这个 List 来获取每个 Future 的结果。问题是大多数时候有些期货永远不会返回,即使演员声称它已经发送了回复。问题是随机发生的,有时它会通过整个列表,但大多数时候它会卡在某个点并无限期挂起。

这是一些在我的机器上产生问题的代码:

水槽.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
                }
        }
    }
 }
}

来源.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()
    }
}

我究竟做错了什么?

4

2 回答 2

2

我猜你的问题是由于这一行:

futures.foreach( f => println(f()))

在其中您循环遍历所有期货并依次阻止每个期货,等待其结果。封锁期货通常是一个坏主意,应该避免。相反,您要做的是指定在未来结果可用时执行的操作。尝试这个:

futures.foreach(f => f.foreach(r => println(r)))

这是用 for 理解的另一种说法:

for (future <- futures; result <- future) { println(result) }

这篇博文是关于期货阻塞问题以及一元期货如何克服它的优秀入门读物。

于 2010-07-28T20:50:02.000 回答
0

我也见过类似的案例。当线程内部的代码抛出某些类型的异常并退出时,对应的future.get 永远不会返回。可以尝试引发 java.lang.Error 与 java.lang.NoSuchMethodError 的异常。后者对应的未来永远不会回来。

于 2014-11-05T17:42:03.307 回答