一、Actor
1.Actor模型
Actor模型是一个并发编程的数学模型。当接收到一个消息后,actor可以做出以下反应:做出本地决策,创造更多actor,发送更多消息,并且决定如何对下一条消息做出反应。Actor可以改变自己的状态,但是只能通过消息传递来影响其他actor(避免了锁的使用,实际场景中锁是一个相当烦的东西)。
2.生命周期
Actor 交给开发者的是一个引用,这个引用包括 path和UID,即可定位一个 Actor
preStart() 在 actor 启动后,处理第一条消息之前被调用。
postStop() 在 actor 停止之前调用,调用后不再接收消息。
preRestart() 在重启 Actor 之前在旧实例上调用
postRestart() 在重启 Actor 之后在新实例上调用,Actor.scala默认的postRestart()方法调用了preStart()方法
:当进行 restart 时,在 MyWork 中打印了uid和path,以及 Object 的 hash 值。
Resume: 当 resume 时,只有 preStart 被调用。
Stop: 节点 Stop 时,会先调用其所有子 actor 的 postStop() 方法。
3.props()
静态方法 props() 用来构造这个 Actor 的实例
Props.create(PongActor.class, arg1, arg2, argn);
4.onReceive(Object msg)
onReceive(Object msg)方法是 Actor 的核心逻辑,Actor 接收到的消息都放在 MailBox 中,从这个 MailBox 中取出来的一条一条消息就通过这个方法进行处理。可以对不同消息定义不同的动作。
5.Actor 实例的引用叫做ActorRef
ActorRef actor = actorSystem.actorOf(Props.create(JavaPongActor.class));
6.watch系列
(1)一个 Actor a 可以监控另一个 Actor b,当b被 context stop 或被 PoisonPill 毒死后,a 会收到一个 Terminated 信号。
有两种 watch 方式:第一种是 watch 一个独立的 Actor,第二种是 watch 子Actor
(2)这里需要注意,虽然父Actor享有对子Actor的一切生杀大权,但是 需要在父Actor中显示的调用getContext.watch(childActorRef),才会当子Actor停止运行后收到Terminated消息。
7.剖析Actor
(1)AbstractActor:首先,我们继承了AbstractActor
(2)Receive:AbstractActor 类有一个receive 方法,其子类必须实现这个方法或是通过
构造函数调用该方法。receive 方法返回的类型是PartialFunction。
Akka 为我们提供了一个抽象的构造方法类receiveBuilder,用于生成PartialFunction 作为返回值。
(3)receiveBuilder:连续调用receiveBuilder 的方法,为所有需要匹配处理的输入消
息类型提供响应方法的描述, 然后调用build() 方法生成需要返回的PartialFunction
(4)Match:receiveBuilder 提供了一些值得一提的match 方法,我们将提供一些示例,
展示如何分别使用这些方法来匹配“ping”消息。
(4.1)match(class, function):描述了对于任何尚未匹配的该类型的示例,应该如
何响应。
match(String.class, s -> {if(s.equals("Ping")) respondToPing(s);})
(4.2)match(class, predicate, function):描述了对于predicate 条件函数为真的某特
定类型的消息,应该如何响应。
match(String.class, s -> s.equals("Ping"), s -> respondToPing(s))
(4.3)matchEquals(object, function):描述了对于和传入的第一个参数相等的消
息,应该如何响应。
matchEquals("Ping", s -> respondToPing(s))
(4.4) matchAny(function):该函数匹配所有尚未匹配的消息。通常来说,最佳实
践是返回错误信息,或者至少将错误信息记录到日志,帮助开发过程中的错误调试。
8.有4种核心的Actor消息模式:tell、ask、forward和pipe
Ask:向Actor 发送一条消息,返回一个Future。当Actor 返回响应时,会完成
Future。不会向消息发送者的邮箱返回任何消息。
Tell: 向Actor 发送一条消息。所有发送至sender()的响应都会返回给发送消息的
Actor。
Forward:将接收到的消息再发送给另一个Actor。所有发送至sender()的响应都
会返回给原始消息的发送者。
Pipe:用于将Future 的结果返回给sender()或另一个Actor。如果正在使用Ask
或是处理一个Future,那么使用Pipe 可以正确地返回Future 的结果