0

我正在创建一个演员,我想第一次创建它,然后在需要该演员时使用它的演员参考。这是代码

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而不再次创建它?

4

1 回答 1

3

要实现您的目标,您只需要:

object ActorManager {
  val getTestActorRef: ActorRef = system.actorOf(Props[TestActor], name = "testActor")
}

这将创建一次演员并且它将可用。你不需要actorSelection、同步等所有这些东西。

因此,您将获得对 ActorRef 的静态引用,您可以使用它来发送消息。此参考的 Actor 将在后台创建一次。

于 2018-03-29T15:20:43.873 回答