akka中的 actor和message

參考https://developer.lightbend.com/guides/akka-quickstart-java/define-actors.html

Messages可以是各種類型

Hello World Actors 用了三種類型

  • WhoToGreet:拜訪接受者

  • Greet:執(zhí)行拜訪的說明

  • Greeting : 包含拜訪的消息

定義好了Actors和Messages,需要注意下面幾點:

  • 因為Messages是公共的API,所以一個最佳實踐就是消息應(yīng)該有一個好的名字,豐富的語義,特定作用域,甚至可以包括數(shù)據(jù)類型。這樣易用,容易理解,容易調(diào)試。
  • Messages應(yīng)該不變的,因為多個線程直接共享。
  • 還有一個最佳實踐,把和actor相關(guān)聯(lián)的消息,作為一個靜態(tài)類放在Actor的類中。 這樣就容易理解這個Actor期望和處理哪種類型的消息。
  • 還有一個常用的做法,在Actor中用靜態(tài)的props的描述如何去構(gòu)建這個Actor。

Greeter 和 Printer中使用最佳實踐

The Greeter Actor

從Greeter.java 中截取的一部分

package com.lightbend.akka.sample;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import com.lightbend.akka.sample.Printer.Greeting;

public class Greeter extends AbstractActor {
  static public Props props(String message, ActorRef printerActor) {
    return Props.create(Greeter.class, () -> new Greeter(message, printerActor));
  }

  static public class WhoToGreet {
    public final String who;

    public WhoToGreet(String who) {
        this.who = who;
    }
  }

  static public class Greet {
    public Greet() {
    }
  }

  private final String message;
  private final ActorRef printerActor;
  private String greeting = "";

  public Greeter(String message, ActorRef printerActor) {
    this.message = message;
    this.printerActor = printerActor;
  }

  @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());
        })
        .build();
  }
}

讓我們來分解下代碼:

  • Greeter繼承了AbstractActor重寫了createReceive方法。
  • Greeter構(gòu)造函數(shù)接受兩個參數(shù):String message 用于構(gòu)建Greeting message, ActorRef printerActor是處理問候結(jié)果的Actor的引用。
  • receiveBuilder定義了對不同消息應(yīng)該有不同的反應(yīng)。一個Actor是可以有狀態(tài)的。獲取和改變內(nèi)部狀態(tài)是線程安全的,因為它被Actor model保護著。createReceive會按著Actor所期望的那樣去處理消息。對于Greeter,它處理兩種Message類型,WhoToGreet和Greet。前者會更新Actor的greeting狀態(tài),后者會觸發(fā)發(fā)送消息到Printer Actor。
  • greeting變量包含著Actor的狀態(tài),默認被設(shè)置為''
  • 靜態(tài)的props方法創(chuàng)建和返回一個Props實例。 Props實例是一個創(chuàng)建Actors參數(shù)集的配置類??梢哉J為他是一個不變的和可以被自由分享的菜單來創(chuàng)建Actor,可以包含部署的信息。這個例子,簡單傳遞用于構(gòu)建Actor所需要的參數(shù)。

Printer Actor

  • 它創(chuàng)建日志通過Logging.getLogger(getContext().getSystem(), this); 這樣后就可以通過log.info() 來寫日志。
  • 它處理一種message, Greeting. 然后輸出日志。
package com.lightbend.akka.sample;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.event.Logging;
import akka.event.LoggingAdapter;

public class Printer extends AbstractActor {
  static public Props props() {
    return Props.create(Printer.class, () -> new Printer());
  }

  static public class Greeting {
    public final String message;

    public Greeting(String message) {
      this.message = message;
    }
  }

  private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);

  public Printer() {
  }

  @Override
  public Receive createReceive() {
    return receiveBuilder()
        .match(Greeting.class, greeting -> {
            log.info(greeting.message);
        })
        .build();
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容