Actor是Akka中的核心概念,它为并发和分布式提供了一种更高级别的抽象,使并发编程更加容易。
创建Actor
定义Actor
定义一个Actor非常简单:继承Actor,并提供receive方法即可。
不带构造参数的Actor:
class MyActor1 extends Actor {
val log = Logging(context.system, this)
def receive = {
case "test" => log.info("receive test")
case _ => log.info("receive unkonow message")
}
}
带构造参数的Actor:
class MyActor2(name: String) extends Actor{
println("Actor Name:" + name)
val log = Logging(context.system, this)
def receive = {
case "test" => log.info("receive test")
case _ => log.info("receive unkonow message")
}
}
创建Actor
创建Actor的常见方式有两种,一种是在ActorSystem上创建Actor,另一种是在一个Actor中创建另一个Actor,构成Actor监管树。
1)在ActorSystem上创建Actor:
val system = ActorSystem("MyActorSystem")
//创建不带构造参数的Actor
val myActor1 = system.actorOf(Props[MyActor1], name="actor1")
//创建带构造参数的Actor
val myActor = system.actorOf(Props(new MyActor2("actor2")) name="actor2")
其中name参数是可选的,它指名当前Actor的名称。
2)在Actor中创建Actor
接触Actor的内置对象context来完成,该对象表示当前Actor的上下文
class FirstActor extends Actor{
def receive = {
case "create" => {
val actor1 = context.actorOf(Props[MyActor1])
val actor2 = context.actorOf(Props(new MyActor2("name")));
}
}
}
用这种方式创建的actor与当前actor构造建管树,当前actor相当于新创建的actor的父actor,可以对actor1与actor2进行生命周期监控。
Actor中常用的内置对象
在Actor中有几个常用的内置对象:
self 表示当前actor的ActorRef引用
sender 表示最近接收到的消息的发送actor,通常用该对象进行消息回复
context 表示当前actor的上下文,这个一个很有用的内置对象
- 1)用于创建子actor的工厂方法(actorOf)
context.actorOf(Props[MyActor1], name = "actor1")
- 2)获取actor所属的ActorSystem
context.system
- 3)获取父监管actor
context.parent
- 4)获取监管的所有子actor
context.children
- 声明周期监控
Actor的钩子方法
Actor提供了四个Hook方法用以对Actor的生命周期进行管理,这四个方法分别是 preStart / preRestart / postRestart / postStop,preStart方法在Actor被启动前调用,通常用来做初始化,preRestart在重启Actor之前调用,postRestart在Actor被重启后调用,postStop 在Actor被停止后调用,通常用来清理资源。
一下是四个钩子方法的默认实现:
def preStart() {}
def preRestart(reason: Throwable, message: Option[Any]) {
context.children foreach (context.stop(_))
postStop()
}
def postRestart(reason: Throwable) { preStart() }
def postStop() {}