2010-08-03 79 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