将Actor状态变量声明为可变状态变量

时间:2015-10-03 04:26:00

标签: scala concurrency akka

我对Akka框架和并发概念相当新。从Akka docs中,我了解到一次只能处理Actor邮箱中的一条消息。所以单线程一次处理Actor的状态。我怀疑的是,因此将一个Actor状态/数据变量声明为可变 - 'Var'(仅当'Val'不适合时),在并发的情况下不会导致不一致的Actor状态。 我正在使用Scala进行开发。在下面的主演员中,工人的详细信息存储在可变变量“工人”中。这会是并发问题吗?

class Master extends PersistentActor with ActorLogging {

    ...
    private var workers = Map[String, WorkerState]()
    ...
    }

2 个答案:

答案 0 :(得分:2)

我认为你做得很好。正如你所说,Akka演员的一个基本保证是一个演员将一次处理一条消息,因此不会有不一致的演员状态。

  

Akka演员在概念上每个都有自己的轻量级线程,   这完全屏蔽了系统的其他部分。这意味着   而不是必须使用锁来同步访问权限   编写你的演员代码而不必担心并发性。

http://doc.akka.io/docs/akka/snapshot/general/actors.html

此外,您使用var代替带有可变地图的val是件好事。)

答案 1 :(得分:0)

考虑这些编码情况的另一种方法是在处理每条消息后改变actor的“状态”。例如:

class Master extends PersistentActor with ActorLogging {

  type MyStateType = ... // eg. Map[String, WorkerState], or an immutable case class - of course, feel free to just inline the type...

  def receive = handle(initState) // eg. just inline a call to Map.empty

  def handle(state: MyStateType): Actor.Receive = LoggingReceive {

    case MyMessageType(data) => 

      ... // processing data - build new state

      become(handle(newState))

    case ... // any other message types to be handled, etc.

  }

  ... // rest of class implementation

}

虽然这里仍然存在可变状态(在这种情况下,它是整个演员的状态 - 它实际上变成了“非有限状态机”),但它感觉更好地包含/隐藏(对我来说,至少),并且任何给定消息的actor可用的“state”(或“worker”)被视为完全不可变。