2010-08-03 68 views
2

我有以下阶代码:Scala的演员非演员相互作用(或同步消息从一个演员到servlet)

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请求获得唯一的随机数(当然,随机数只是为了解释问题)。一些提示或参考将不胜感激。

回答

3

可以使用:

!! < - 返回未来,你可以等待

!? < - 使用一个具有超时,则完全同步是很危险的

鉴于你的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

+0

它是一个好的想法,除了使用!要么 !?代替!在上面的代码中,我需要修改RNG对象(即,在某处添加回复语句)。至少,这是我的理解。但是,我不允许修改该对象。 – Jus12 2010-08-03 16:14:17

+0

鉴于你RNG的定义,它工作得很好: 斯卡拉>高清富= FOO {的println(RNG(1000,GetRandom)。!?)}:单位 斯卡拉> FOO 一些(-1025916420) 斯卡拉> foo 部分(-1689041124) scala> foo 部分(-1633665186) – 2010-08-03 19:41:07

+0

这很有趣。我读过,接收演员(即'RNG')必须使用'reply(message)'来回应,而不是使用'sender!消息'为了'!?'工作。但是,它也在我的代码中以这种方式工作。这是预期的吗?谢谢你的提示,顺便说一句。 – Jus12 2010-08-03 22:40:06