Scala中akka actor系统中的全局变量

时间:2016-12-19 15:07:30

标签: scala akka actor

我目前在Scala代码中使用了akka Actor系统。我有一个父演员和一个儿童演员。我想要做的是在父actor发起一个List并让子actor:

i)生成新元素并将它们发送给将它们附加到列表的父级演员。 ii)随时可以访问列表元素。

我如何实现第二(ii)部分?

3 个答案:

答案 0 :(得分:3)

必须 使用消息传递。在两个演员之间分享任何可变状态都违反了Akka提供的所有保证。

或者,您可以在您的子actor和父actor之间共享代理,这将使列表的更新线性化,同时允许同步读取。

答案 1 :(得分:1)

您可以选择父母可以回复披露其内部状态的特定消息。请参阅以下示例:

  import scala.collection.immutable.Queue

  class Parent extends Actor {
    import Parent._

    // TODO: start children here

    override def receive: Receive = receiveElements(Queue.empty[Element])

    def receiveElements(acc: Queue[Element]): Receive = {
      case e@Element => context.become(receiveElements(acc :+ e))
      case GetElements => sender ! acc
    }
  }

  object Parent {
    case class Element(s: String)
    case object GetElements
  }

请注意,通过在父级内部保留var queue而不是使用context.become +递归,可以实现相同的行为。

此外,没有设计一种刷新队列的方法可能会导致OOME。

答案 2 :(得分:-1)

好吧,我设法找到了解决方案。

如果在父Actor中创建变量并将其作为构造参数传递给子Actor,则如果不替换它,则此变量中的每个更改都是可见的。我将用一个错误的例子来解释一个正确的例子。

class ParentActor(/*constructors here*/) extends Actor{
   val list =ListBuffer[Int](1,2)
   child = new ChildActor(list //+other constructors)

   list=ListBuffer[Int](1,2,3) // **wrong** child will see list=List(1,2)
   list+=3         // **right**  child will see list=List(1,2,3) as wanted

}

class ChildActor(list : ListBuffer[Int] /*++ otherconstructors here*/) extends Actor{

       list=ListBuffer[Int](1,2,3,4) // **wrong** parent will see list=List(1,2,3)
       list+=4           // **right**  child will see list=List(1,2,3,4) as wanted

}