我正在创建一个actor,我想第一次创建它,然后在需要该actor时使用它的actor引用。这是代码
val actorPath = "akka://testActorSystem/user/'"
object ActorManager {
def getTestActorRef: ActorRef = {
var actorRef: Option[ActorRef] = None
this.synchronized {
val sel = system.actorSelection(actorPath + "testActor");
val future1 = sel.resolveOne()
val res: Try[ActorRef] = Await.ready(future1, timeout.duration).value.get
res match {
case Success(actorref) =>
actorRef = Some(actorref)
actorRef.get
case Failure(e) =>
val testActor = system.actorOf(Props[TestActor], name = "testActor")
actorRef = Some(testActor)
}
getActorRef(actorRef.get)
}
actorRef.get
}
}
Q1->这是实现我所需功能的正确方法吗? 我遇到的问题是每当在两个地方同时调用此代码时。
ActorManager.getTestActorRef
它引发了两个不同的例外:
akka.actor.ActorNotFound: Actor not found for: ActorSelection[Anchor(akka://testActorSystem/), Path(/user/'testActor)]
at akka.actor.ActorSelection$$anonfun$resolveOne$1.apply(ActorSelection.scala:65) ~[akka-actor_2.11-2.3.6.jar:na]
at akka.actor.ActorSelection$$anonfun$resolveOne$1.apply(ActorSelection.scala:63) ~[akka-actor_2.11-2.3.6.jar:na]
和
akka.actor.InvalidActorNameException: actor name [testActor] is not unique!
at akka.actor.dungeon.ChildrenContainer$NormalChildrenContainer.reserve(ChildrenContainer.scala:130) ~[akka-actor_2.11-2.3.6.jar:na]
at akka.actor.dungeon.Children$class.reserveChild(Children.scala:77) ~[akka-actor_2.11-2.3.6.jar:na]
at akka.actor.ActorCell.reserveChild(ActorCell.scala:369) ~[akka-actor_2.11-2.3.6.jar:na]
我尝试使用this.synchronized
,但没有帮助,当我多次调用此方法时会出现问题
ActorManager.getTestActorRef
我怎样才能创建一次actor并一次又一次地使用它的actorRef而不再创建它?
答案 0 :(得分:3)
要实现您的目标,您需要:
object ActorManager {
val getTestActorRef: ActorRef = system.actorOf(Props[TestActor], name = "testActor")
}
这将创建一次actor,它将可用。你不需要使用actorSelection,synchronized等所有这些东西。
因此,您将获得可用于发送消息的ActorRef的静态引用。此参考的Actor将在后台创建一次。