• Akka Quickstart with Java-笔记


    官方文档: http://developer.lightbend.com/guides/akka-quickstart-java/?_ga=2.177525157.1012573474.1504767665-546319647.1504766934

    一. AKKA Hello World example : 

    1.首先需要创建一个ActorSystem, 它是所有Actor运行的容器.

    2.其次创建Greeter Actor和Printer Actor.

    3.发送消息到Greeter Actor实例, 它们会先在内部存储消息.

    4.最后Greeter Actor里面的指令消息会触发它们发送消息给Printer Actor, 然后Printer Actor会执行对应的操作.

     二. 定义Actors和messages

    messages可以是任意类型(any subtype of Object).

    当定义Actors和它们的messages时, 要遵守以下规范:

    1.因为messages是Actor的公共API, 所以给messages定义名称的时候要富含语义以及特定领域的意义.

    2.messages是不可变的, 因为它们在不同的线程之间共享.

    3.把Actor相关的messages作为静态内部类放到Actor类中, 这样更容易理解actor需要处理什么类型的消息.

    4.在Actor类中, 使用静态方法props描述如何构造Actor.

     1 package com.lightbend.akka.sample;
     2 
     3 import akka.actor.AbstractActor;
     4 import akka.actor.ActorRef;
     5 import akka.actor.Props;
     6 import com.lightbend.akka.sample.Printer.Greeting;
     7 
     8 public class Greeter extends AbstractActor {
     9   static public Props props(String message, ActorRef printerActor) {
    10     return Props.create(Greeter.class, () -> new Greeter(message, printerActor));
    11   }
    12 
    13   static public class WhoToGreet {
    14     public final String who;
    15 
    16     public WhoToGreet(String who) {
    17         this.who = who;
    18     }
    19   }
    20 
    21   static public class Greet {
    22     public Greet() {
    23     }
    24   }
    25 
    26   private final String message;
    27   private final ActorRef printerActor;
    28   private String greeting = "";
    29 
    30   public Greeter(String message, ActorRef printerActor) {
    31     this.message = message;
    32     this.printerActor = printerActor;
    33   }
    34 
    35   @Override
    36   public Receive createReceive() {
    37     return receiveBuilder()
    38         .match(WhoToGreet.class, wtg -> {
    39           this.greeting = message + ", " + wtg.who;
    40         })
    41         .match(Greet.class, x -> {
    42           printerActor.tell(new Greeting(greeting), getSelf());
    43         })
    44         .build();
    45   }
    46 }
     1 package com.lightbend.akka.sample;
     2 
     3 import akka.actor.AbstractActor;
     4 import akka.actor.ActorRef;
     5 import akka.actor.Props;
     6 import akka.event.Logging;
     7 import akka.event.LoggingAdapter;
     8 
     9 public class Printer extends AbstractActor {
    10   static public Props props() {
    11     return Props.create(Printer.class, () -> new Printer());
    12   }
    13 
    14   static public class Greeting {
    15     public final String message;
    16 
    17     public Greeting(String message) {
    18       this.message = message;
    19     }
    20   }
    21 
    22   private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
    23 
    24   public Printer() {
    25   }
    26 
    27   @Override
    28   public Receive createReceive() {
    29     return receiveBuilder()
    30         .match(Greeting.class, greeting -> {
    31             log.info(greeting.message);
    32         })
    33         .build();
    34   }
    35 }

    三.创建Actor对象

    Actor不能用过new来创建, 而是通过工厂来创建Actor对象, 工厂返回的不是actor实例, 而是一个引用akka.actor.ActorRef, 这个引用指向actor实例.

    akka.actor.ActorSystem类似于Spring的BeanFactory. 它作为Actor的容器, 管理actor的生命周期. 工厂方法actorOf通过两个参数创建Actor对象, 一个参数是配置对象Props, 一个参数是actor的名称.

    1 final ActorRef printerActor = 
    2   system.actorOf(Printer.props(), "printerActor");
    3 final ActorRef howdyGreeter = 
    4   system.actorOf(Greeter.props("Howdy", printerActor), "howdyGreeter");
    5 final ActorRef helloGreeter = 
    6   system.actorOf(Greeter.props("Hello", printerActor), "helloGreeter");
    7 final ActorRef goodDayGreeter = 
    8   system.actorOf(Greeter.props("Good day", printerActor), "goodDayGreeter");

    四. 异步通信

    Actor是响应式的和消息驱动的. 一个Actor不会做任何事情知道它接收到一个消息.Actors通过异步消息来通信. 这确保了消息的发送者(sender)不用停下来等待它们的消息被接受者(recipient)处理. 相反的, 发送者只要把消息放到接收者的邮筒(mailbox)里后就可以去干别的事了. 而这个邮筒本子上是一个有序的消息队列. 来自同一个Actor的多条消息是有序的, 而来自不同的Actor的消息是交错的.

    当actor不处理消息的时候是处于一个暂停的状态, 此时它不消耗除内存以外的任何资源.

    五. 发送消息到Actor

    把消息放到Actor的邮筒(mailbox)里, 需要调用ActorRef的tell方法.  举个栗子:

    把消息发送给Greeter Actor :

     1 howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());
     2 howdyGreeter.tell(new Greet(), ActorRef.noSender());
     3 
     4 howdyGreeter.tell(new WhoToGreet("Lightbend"), ActorRef.noSender());
     5 howdyGreeter.tell(new Greet(), ActorRef.noSender());
     6 
     7 helloGreeter.tell(new WhoToGreet("Java"), ActorRef.noSender());
     8 helloGreeter.tell(new Greet(), ActorRef.noSender());
     9 
    10 goodDayGreeter.tell(new WhoToGreet("Play"), ActorRef.noSender());
    11 goodDayGreeter.tell(new Greet(), ActorRef.noSender());

    Greeter Actor给Printer Actor发送消息:

    printerActor.tell(new Greeting(greeting), getSelf());
  • 相关阅读:
    网易编程题——小易喜欢的单词
    Effective C++ 条款12:复制对象时勿忘其每一个成分
    Effective C++ 条款11:在operator=中处理"自我赋值"
    STM32-通用定时器基本定时功能
    GPIO_Mode
    STM32的ADC编程方法
    STM32的ADC采样与多通道ADC采样
    网络子系统
    linux网络子系统内核分析
    Linux 中高效编写 Bash 脚本的 10 个技巧
  • 原文地址:https://www.cnblogs.com/CoolJayson/p/7490946.html
Copyright © 2020-2023  润新知