scala akka actor的入门(2)-actor的结构

1.一个actor 总有一个父节点
system.actorOf() 创建是系统actor的子actor
context.actorOf() 创建是该actor的子actor
这里写图片描述
2.

import akka.actor.{Actor, ActorSystem, Props}
class PrintMyActorRefActor extends Actor {
  override def receive: Receive = {
    case "test" =>
      val secondRef = context.actorOf(Props.empty, "second-actor")
      println(s"Second: $secondRef")
  }
}

object ActorHierarchyExperiments extends App {
  val system = ActorSystem("testSystem")

  val firstRef = system.actorOf(Props[PrintMyActorRefActor], "first-actor")
  println(s"First: $firstRef")
  firstRef ! "test"


}

输出结果为:

First: Actor[akka://testSystem/user/first-actor#-1025274301]
Second: Actor[akka://testSystem/user/first-actor/second-actor#-467743039]

我们可以看到输出的子actor包含了父actor的路径

3.actor的生命周期
当一个actor结束的时候,它的所有子actor都会递归结束
一般用context.stop(self) 结束自身actor
结束其他actor 用发送“毒药”的方式 而不是用context.stop(actorRef),一般有preStart() postStop()

preStart() :在actor 启动还没有接受第一个消息时用
postStop():在actor结束前,没有处理消息的时候

例子:

class StartStopActor1 extends Actor {
  override def preStart(): Unit = {
    println("first started")
    context.actorOf(Props[StartStopActor2], "second")
  }
  override def postStop(): Unit = println("first stopped")

  override def receive: Actor.Receive = {
    case "stop" => context.stop(self)
  }
}

class StartStopActor2 extends Actor {
  override def preStart(): Unit = println("second started")
  override def postStop(): Unit = println("second stopped")

  // Actor.emptyBehavior is a useful placeholder when we don't
  // want to handle any messages in the actor.
  override def receive: Actor.Receive = Actor.emptyBehavior
}
object test extends App{
  val system: ActorSystem = ActorSystem("test")

  //#create-actors
  // Create the printer actor
  val first: ActorRef = system.actorOf(Props[StartStopActor1], "printerActor")

  first ! "stop"
}

输出结果为:

first started
second started
second stopped
first stopped

4.当子actor失败的时候
例子:

class SupervisingActor extends Actor {
  val child = context.actorOf(Props[SupervisedActor], "supervised-actor")

  override def receive: Receive = {
    case "failChild" => child ! "fail"
  }
}

class SupervisedActor extends Actor {
  override def preStart(): Unit = println("supervised actor started")
  override def postStop(): Unit = println("supervised actor stopped")

  override def receive: Receive = {
    case "fail" =>
      println("supervised actor fails now")
      throw new Exception("I failed!")
  }
}
object test extends App{
  val system: ActorSystem = ActorSystem("test")

  //#create-actors
  // Create the printer actor
  val first: ActorRef = system.actorOf(Props[SupervisingActor], "supervisingActor")

  first ! "failChild"
}

输出结果为:

supervised actor started
supervised actor fails now
supervised actor stopped
supervised actor started
[ERROR] [01/10/2018 16:00:28.230] [test-akka.actor.default-dispatcher-3] [akka://test/user/supervisingActor/supervised-actor] I failed!
java.lang.Exception: I failed!
    at SupervisedActor$$anonfun$receive$2.applyOrElse(test.scala:21)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)
    at akka.actor.ActorCell.invoke(ActorCell.scala:456)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)
    at akka.dispatch.Mailbox.run(Mailbox.scala:219)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

我们可以看到当actor挂了的时候,它立刻就重启了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值