如何在scala中使用同步

时间:2018-03-29 14:50:45

标签: scala akka akka-actor

我正在创建一个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而不再创建它?

1 个答案:

答案 0 :(得分:3)

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

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

这将创建一次actor,它将可用。你不需要使用actorSelection,synchronized等所有这些东西。

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

相关问题