akka初学2

来源:互联网 发布:coc5级女武神升级数据 编辑:程序博客网 时间:2024/06/06 00:52

这里还有一个更复杂的例子,涉及到两个actor的交互。 就像两个人在乒乒乓乓的打乒乓球。 两个actor来回的ping pang,直到达到特定的次数才停止。

这里定义了两个actor: Ping和Pang。

Ping 接收StartMessage和 PongMessage。 StartMessage是一个启动消息,由main对象发送,PongMessage来自Pong actor,如果次数还未达到,它继续发送PingMessage。Pong 接收StopMessage和 PingMessage。 如果接收到PingMessage,它就发送一个PongMessage, 如果是StopMessage, 停止ActorSystem

这里调用了Ping的带参数的构造函数 Props(new Ping(pong))

package akka.scala.liuweiimport akka.actor.{Actor, ActorRef, ActorSystem, Props}case object PingMessagecase object PongMessagecase object StartMessagecase object StopMessage/**  * Created by liuwei on 2017/5/12.  */class Ping(pong:ActorRef) extends Actor {  var count = 0  def incrementAndPrint {count += 1; println(s"$count:ping")}  def receive: Receive = {    case StartMessage =>      incrementAndPrint      pong ! PongMessage    case PingMessage =>      incrementAndPrint      if(count > 9) {        sender ! StopMessage        println("ping stopped")        context.stop(self)      }      else        sender ! PongMessage    case _ => println("Ping got unexpected information")  }}class Pong extends Actor {  var count = 0  def receive = {    case StopMessage =>      println("pong stopped")      //context.stop方法来结束      context.stop(self)    case PongMessage =>      count += 1      println(s"$count:pong")      sender ! PingMessage    case _ => println("Pong got unexpected information")  }}object PingPangTest extends App{  val system = ActorSystem("PingPongTest")  //创建Pong的actor实例(pongActor对象其实是ActorRef的实例);  val pongActor = system.actorOf(Props[Pong], name="pong") // Ping的actor实例,其构造函数接受ActorRef参数;  val pingActor = system.actorOf(Props(new Ping(pongActor)),    name = "ping")  //通过给pingActor发送一个StartMessage消息来启动pingActor和pongActor的具体动作  pingActor ! StartMessage}

在ActorSystem层面,通过调用system.actorOf方法来创建actors;在actor内部,通过调用context.actorOf方法来创建子actor

package akka.scalaimport akka.actor.{Actor, ActorSystem, PoisonPill, Props}/**  * Created by liuwei on 2017/5/10.  */case class CreateChild (name: String)case class Name (name: String)class Child extends Actor {  var name = "No name"  /**    *  关闭文件或数据库连接    */  override def postStop: Unit = {    println(s"D'oh! They killed me ($name): ${self.path}")  }  def receive = {    case Name(name) => this.name = name    case _ => println(s"Child $name got message.")  }}class Parent extends Actor {  def receive = {    case CreateChild(name) =>      // Parent creates a new Child here      println(s"Parent about to create Child ($name) ...")      //创建子actor      val child = context.actorOf(Props[Child], name=s"$name")      child ! Name(name)    case _ => println(s"Parent got some other message.")  }}object ParentChildDemo extends App{  val actorSystem = ActorSystem("ParentChildTest")  val parent = actorSystem.actorOf(Props[Parent], name="Parent")  // send messages to Parent to create to child actors  parent ! CreateChild("XiaoMing")  parent ! CreateChild("XiaoLiang")  Thread.sleep(500)  // lookup XiaoMing, the kill it  println("Sending XiaoMing a PoisonPill ... ")  val xiaoming = actorSystem.actorSelection("/user/Parent/XiaoMing")  /**    * PoisonPill和gracefulStop还有其他两种方式,发送PoisonPill消息或者使用gracefulStop终止。你也可以向actor发送akka.actor.PoisonPill消息,这个消息处理完成后actor会被终止。PoisonPill与普通消息一样被放进队列,因此会在已经入队列的其它消息之后被执行。    */  xiaoming ! PoisonPill  println("XiaoMing was killed")  Thread.sleep(5000)  actorSystem.terminate()}




0 0
原创粉丝点击