我知道actor模型的一个优点是,一次只处理一条消息,简化了并发问题。但在我看来,我的演员正在处理多个消息。在伪代码中,我有演员同时处理多条消息
var status = 0
def receive = {
case DoSomething =>
val dest = sender()
status = 0
for {
otherActor <- resolveOtherActor("/user/OtherActor")
} yield {
for {
res <- {status = 1
otherActor ? doSomething1
}
res <- {status = 2
otherActor ? doSomething2
}
} yield {
dest ! status
}
}
case GetStatus => sender() ! status
}
如果我发送一个DoSomething的消息,这个演员,然后立即发送到的getStatus这个演员再三,我会看到状态0,1和2回来的序列。如果actor模型一次只处理一条消息,我只会看到状态2被返回,因为我不能访问中间状态。
看来,演员模式仍然需要锁。我错过了什么?
锁是没有必要的。问题模式创建一个Future,此时上下文更改和GetStatus消息可以进入,也许这可能是问题。尝试消除询问操作(?)并再试一次。 – EmiCareOfCell44
@ EmiCareOfCell44这是我认为可能发生的事情。然而,在一个使用许多阿卡结构的系统中,有很多'问'和其他未来的操作。所以看起来行动者似乎并不解决并发问题,除非他们不在期货上操作,这可能不是现实的情况。 – Erix
在这种情况下,我不会使用演员内部的问题。如果接收方法必须发送其他消息,我将使用tell(!)来代替。如果你需要知道“otherActor”中发生了什么,这应该发回你需要处理的其他消息来添加另一个'case'子句。应该避免使用可变状态的期货。 – EmiCareOfCell44