“ActorRef.tell”方法的第二个参数是什么?

时间:2018-04-04 11:24:27

标签: java akka actor

我开始学习Akka并从official guid下载了示例:

我不理解tell方法第二个参数用法:

在主要方法中写道:

howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());

因此,第二个参数是ActorRef.noSender()

演员方入口点上的

如下所示:

@Override
public Receive createReceive() {
  return receiveBuilder()
      .match(WhoToGreet.class, wtg -> {
        this.greeting = message + ", " + wtg.who;
      })
      .match(Greet.class, x -> {
        //#greeter-send-message
        printerActor.tell(new Greeting(greeting), getSelf());
        //#greeter-send-message
      })

因此我无法访问传递的引用。

此外,您可以看到此演员在消息类型为Greet.class的情况下向另一位演员发送消息

printerActor.tell(new Greeting(greeting), getSelf());

此处第二个参数为getSelf(),但我尝试使用ActorRef.noSender()进行更改,但行为未发生变化。

打印机actor入口点如下所示:

@Override
public Receive createReceive() {
  return receiveBuilder()
      .match(Greeting.class, greeting -> {
          log.info(greeting.message);
      })
      .build();
}

因此它只打印提供的消息

1 个答案:

答案 0 :(得分:4)

printerActor.tell(new Greeting(greeting), getSelf());
     

此处第二个参数为getSelf(),但我尝试使用ActorRef.noSender()进行更改,但行为未发生变化。

tell()方法的第二个参数是收件人actor可以向其发送回复的发件人引用。换句话说,如果参与者A向参与者B发送消息,其中getSelf()作为tell()调用的第二个参数,则参与者B可以使用getSender()来获取对参与者A的引用。当收件人不需要对发件人的引用时,传递ActorRef.noSender()作为第二个参数是合适的。请注意,您可以使用任何ActorRef作为tell()的第二个参数。

快速入门指南中的打印机角色在收到getSender()消息时不会调用Greeting。打印机actor在收到Greeting消息时唯一要做的就是记录问候语。在这种情况下,使用ActorRef.noSender()而不是getSelf()的绿色演员会更有意义(但是,在这种情况下,它没有任何区别,因为打印机演员没有调用getSender()):

printerActor.tell(new Greeting(greeting), ActorRef.noSender());

如果您想了解如何使用发件人参考,您可以更改打印机角色的行为:

@Override
public Receive createReceive() {
  return receiveBuilder()
    .match(Greeting.class, greeting -> {
      log.info(greeting.message);
      getSender().tell(new PrinterAck(), ActorRef.noSender());
  })
  .build();
}

然后更改greeter actor以处理PrinterAck消息(显然您需要定义PrinterAck类):

@Override
public Receive createReceive() {
  return receiveBuilder()
    .match(WhoToGreet.class, wtg -> {
      this.greeting = message + ", " + wtg.who;
    })
    .match(Greet.class, x -> {
      printerActor.tell(new Greeting(greeting), getSelf());
    })
    .match(PrinterAck.class, x -> {
      log.info("Received an ack from the printer actor.");
    })
    .build();
}