zoukankan      html  css  js  c++  java
  • akka-actor第一课

    1、从akka内的系统ActorSystem得知整个代码簇中的设置从actor与之相关的ActorSystem(),

    可知:ActorSystem是一个重量级结构,它将分配线程,因此请为每个逻辑应用程序创建一个线程。通常ActorSystem每个JVM进程一个。

    能够知道大体的结构关系:

    • 重要的是要注意,actor在不再被引用时不会自动停止,创建的每个Actor也必须明确销毁。唯一的简化是,停止父Actor也将递归停止该父Actor创建的所有子Actor
    • 顶级参与者(也称为用户监护者参与者)与一起创建ActorSystem发送到参与者系统的消息被定向到根参与者。根actor由用于创建的行为定义ActorSystem,下图中即GreetStarter()
    • Actor可以创建或生成任意数量的子角色Actor,这些子角色又可以生成自己的子角色,从而形成一个角色层次结构。托管层次结构,并且只能有一个根actor,一个角色在层次结构的顶部。
    • children actor 的生命周期与父母actor息息相关,即:一个孩子可以停下来或随时被停下来,但永远不能超过其父母。

    2、最简单的Actor

    • 单向的Actor,需要注意的是收到信息的时候的
    ActorContext
    注意:Behaviors.receive的情况

    •   Behaviors.same
      /**
       * Return this behavior from message processing in order to advise the
       * system to reuse the previous behavior. This is provided in order to
       * avoid the allocation overhead of recreating the current behavior where
       * that is not necessary.从消息处理返回此行为,以便通知系统来重用以前的行为。
    * 这是为了避免重新创建当前行为的分配开销,这是没有必要的。
    */ def same[T]: Behavior[T] = BehaviorImpl.same

    3、Actor的声明类型与object内部的  apply相关,如在ActorSystem的

    ActorSystem(Printe(),"ghost")
    //返回类型是object Printe的   def apply():Behavior[PrintMes]相关

    4、发送并忘记

       使用tell或!函数向actor发送消息,并且在消息内没有可回复的actor引用字段(如:replyTo: ActoRef[T])既是典型的发送并忘记模式。

    适用的情况范围即为:

    • 消息是否被处理不重要
    • 不需要确保消息被成功交付或处理

    这个模式非常简单,即最简单的一个Actor的案例如下:

    
    
    import akka.actor.typed._
    import scaladsl._

    object
    Printe{ case class PrintMes(message:String) def apply():Behavior[PrintMes] = { Behaviors.receive{ case(ss, PrintMes(message))=> println(message+"Hello World! ") Behaviors.same } } } object FireAndGo extends App { val sys=ActorSystem(Printe(),"ghost") sys ! Printe.PrintMes("mens") sys.terminate() }

    5、Typed Actor

    • Actor有类型,其签名也改成了akka.actor.typed.ActorRef[T]。常有的ActorRef[T]大多是spawn返回的类型,而spawn又有新建子actor的含义。
    def spawn[U](behavior: Behavior[U], name: String, props: Props = Props.empty): ActorRef[U]
    • behavior是要创建的actor,name为子actor的名字,需要保证在同一级内唯一(兄弟之间),props可对actor作一些自定义,如:线程执行器(Dispatcher)、邮箱等。

    故存在几个object内的case class的传递的参数是ActorRef[T]的存在时,需要新引入对象,就像akka actor官网的

    两个actor都需要ActorRef参数,因此引入一个新的对象HelloWorldMain来通过纯String参数来对话,常见的是直接在apply内部spawn新的actor返回ActorRef参数,如下所示:

    import akka.actor.typed.scaladsl.Behaviors
    import akka.actor.typed.scaladsl.LoggerOps
    import akka.actor.typed.{ ActorRef, ActorSystem, Behavior }
    
    object HelloWorld {
      final case class Greet(whom: String, replyTo: ActorRef[Greeted])
      final case class Greeted(whom: String, from: ActorRef[Greet])
    
      def apply(): Behavior[Greet] = Behaviors.receive { (context, message) =>
        println(s"Hello ${message.whom}!")
        message.replyTo ! Greeted(message.whom, context.self)
        Behaviors.same
      }
    }
    
    object HelloWorldBot {
    
      def apply(max: Int): Behavior[HelloWorld.Greeted] = {
        bot(0, max)
      }
    
      private def bot(greetingCounter: Int, max: Int): Behavior[HelloWorld.Greeted] =
        Behaviors.receive { (context, message) =>
          val n = greetingCounter + 1
          println(s"Greeting $n for ${message.whom}")
          if (n == max) {
            Behaviors.stopped
          } else {
            message.from ! HelloWorld.Greet(message.whom, context.self)
            bot(n, max)
          }
        }
    }
    
    object HelloWorldMain {
    
      final case class SayHello(name: String)
    
      def apply(): Behavior[SayHello] =
        Behaviors.setup { context =>
          val greeter = context.spawn(HelloWorld(), "greeter")
    
          Behaviors.receiveMessage { message =>
            val replyTo = context.spawn(HelloWorldBot(max = 3), message.name)
            greeter ! HelloWorld.Greet(message.name, replyTo)
            Behaviors.same
          }
        }
    
      def main(args: Array[String]): Unit = {
        val system: ActorSystem[HelloWorldMain.SayHello] =
          ActorSystem(HelloWorldMain(), "hello")
    
        system ! HelloWorldMain.SayHello("World")
        system ! HelloWorldMain.SayHello("Akka")
      }
    }

  • 相关阅读:
    安装libgl1-mesa-dri:i386重启后黑屏问题解决
    adb连接安卓模拟器
    编译andorid内核
    android镜像文件说明
    ubantu14.04配置android编译环境
    UDP组播相关
    eclipse中如何向开源中国(码云)上传代码
    How to copy a java.util.List into another java.util.List
    Windows中.exe程序的启动过程和C/C++运行时库
    GEF调色板中的多级树结构
  • 原文地址:https://www.cnblogs.com/0205gt/p/12971245.html
Copyright © 2011-2022 走看看