Akka Actor类中的this和self有什么区别?

5
假设我有一个非常简单的 actor 类,它可以接收任何消息并将其打印到控制台。
  class SimpleActor extends Actor{

    def receive: Receive = {
      case message =>
        println(s"[${this}][${self}] received message: ${message}")
    }
  }

  val simpleActor = actorSystem.actorOf(Props[SimpleActor], "simpleActor")
  simpleActor ! "Hey"

你可以看到这里同时使用了thisself,它们的值是不同的。它的输出大致如下:

[pkg.ActorRunner$SimpleActor@65cca69][Actor[akka://ActorDemo/user/simpleActor#934141660]] received message: Hey

我想了解selfthis之间的区别,因为在复杂场景(生产系统)中,如果Actor出现故障,例如抛出异常,则this的值会发生变化。

1个回答

8

this 是指扩展 Actor 特质的对象的经典 Java 引用,而 self 是对需要发送消息(!tell?ask)的 ActorRef 的引用。

  • 无法向 this 发送消息。
  • 在传递 this 的引用之外的 Actor 中传递 self 的引用是完全可以的,事实上,当你从另一个 Actor 向 Actor 发送消息时,它会被隐式地发送。如果将 this 传递给另一个对象,则会危及 Actor 的状态封装。请记住,与 Actor 通信的唯一方式是通过消息,即使用其 ActorRef
  • self 将在 Actor 重新启动后保持有效,也就是说,您可以继续向相同的 ActorRef (self) 发送消息。只有当 Actor 停止时,对 ActorRef 的引用才不再有效,并且发送到该地址的消息将进入 Dead Letters。
  • 在 Actor 重新启动后,this 不再有效。创建 Actor 类型的新对象以清除可能由于故障而被破坏的 Actor 状态。

重新启动的含义

除非故障可以特别识别,否则不能排除第三种情况,这导致结论是需要清除内部状态。如果监管者决定其其他子级或自身不受破坏的影响(例如,因为有意应用了错误内核模式),因此最好重启子代。这是通过创建底层 Actor 类的新实例,并将失败的实例替换为孩子的 ActorRef 中的新实例来执行的;能够做到这一点是封装 Actor 在特殊引用内的原因之一。然后,新 Actor 恢复处理其邮箱,这意味着重新启动在 Actor 之外是不可见的,不过要注意的例外是发生故障的消息不会被重新处理。

Actor 引用和路径相等性

请注意,由故障引起的 Actor 重新启动仍意味着它是相同的 Actor 版本,即消费者看不到重启。

Actor 引用和路径之间的区别是什么?

演员引用指定一个单独的演员,引用的生命周期与该演员的生命周期相匹配;演员路径代表一个可能或可能不被演员居住的名称,路径本身没有生命周期,它永远不会失效。您可以创建一个演员路径而不创建演员,但是您不能创建相应演员而不创建演员引用。
您可以创建一个演员,终止它,然后使用相同的演员路径创建一个新演员。新创建的演员是演员的新体现。它不是同一个演员。对于旧体现的演员引用不适用于新体现。即使它们具有相同的路径,发送到旧演员引用的消息也不会传递给新体现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接