Scala actor到非actor的交互(或者将actor中的消息同步到servlet)

时间:2010-08-03 15:19:56

标签: scala servlets synchronization actor future

我有以下scala代码:

  package dummy
  import javax.servlet.http.{HttpServlet,
    HttpServletRequest => HSReq, HttpServletResponse => HSResp}
  import scala.actors.Actor

  class DummyServlet extends HttpServlet {
    RNG.start
    override def doGet(req: HSReq, resp: HSResp) = {
      def message = <HTML><HEAD><TITLE>RandomNumber </TITLE></HEAD><BODY>
           Random number = {getRandom}</BODY></HTML>
      resp.getWriter().print(message)
      def getRandom: String = {var d = new DummyActor;d.start;d.getRandom}
    }
    class DummyActor extends Actor {
      var result = "0"
      def act = { RNG ! GetRandom
        react { case (r:Int) => result = r.toString }
      }
      def getRandom:String = {
        Thread.sleep(300)
        result
      }
    }
  }

  // below code is not modifiable. I am using it as a library
  case object GetRandom
  object RNG extends Actor {
    def act{loop{react{case GetRandom=>sender!scala.util.Random.nextInt}}}
  }

在上面的代码中,我必须使用thread.sleep来确保result有足够的时间来更新,否则会返回0。在不使用thread.sleep的情况下,这样做更优雅的方法是什么?我想我必须使用期货,但我不能理解这个概念。我需要确保每个HTTP reaquest获得一个唯一的随机数(当然,随机数只是为了解释问题)。一些提示或参考将不胜感激。

1 个答案:

答案 0 :(得分:3)

使用:

!! &lt; - 返回您可以等待的未来

!? &lt; - 使用超时的那个,完全同步是危险的

鉴于你对RNG的定义,可以使用一些REPL代码进行验证:

scala> def foo = { println(RNG.!?(1000,GetRandom)) } 
foo: Unit

scala> foo
Some(-1025916420)

scala> foo
Some(-1689041124)

scala> foo
Some(-1633665186)

文档在这里:http://www.scala-lang.org/api/current/scala/actors/Actor.html