Akka中actor行为的切换实际是actor的receive的函数的选择切换。
通过become()方式切换行为。
在ActorCell中维护着一个可伸缩List实现的行为堆栈。
private var behaviorStack: List[Actor.Receive] = emptyBehaviorStack
在actor接受到消息的时候,将会调用堆栈顶部的函数。
final def receiveMessage(msg: Any): Unit = actor.aroundReceive(behaviorStack.head, msg)
当通过become()切换行为模式的时候,实则就是将新的行为,也就是需要采用的receive函数放到行为堆栈的顶部。
def become(behavior: Actor.Receive, discardOld: Boolean = true): Unit =
behaviorStack = behavior :: (if (discardOld && behaviorStack.nonEmpty) behaviorStack.tail else behaviorStack)
因此,如果不断通过become()函数切换行为,将存在栈溢出的风险,所以如果需要切换行为模式,需要通过unbecome()函数出栈。
def unbecome(): Unit = {
val original = behaviorStack
behaviorStack =
if (original.isEmpty || original.tail.isEmpty) actor.receive :: emptyBehaviorStack
else original.tail
}