翻译:AKKA笔记 - Actor消息 -1(二)
2015-12-27 15:42
288 查看
http://www.cnblogs.com/zhukunrong/p/4808854.html
##消息## 我们只是让QuoteRequest到ActorRef去但是我们根本没见过消息类!它是这样的: (一个最佳实践是把你的消息类包装在一个完整的对象里以利于更好的组织)
TeacherProtocol
package me.rerun.akkanotes.messaging.protocols object TeacherProtocol{ case class QuoteRequest() case class QuoteResponse(quoteString:String) }
就像你知道的,QuoteRequest是用来发给TeacherActor的。Actor应该响应一个QuoteResponse回来。
##分发者DISPATCHER和邮箱MAILBOX##
ActorRef将消息处理功能委托给Dispatcher。在底层实现中,当我们创建一个ActorSystem和ActorRef的时候,一个Dispatcher和一个MailBox也被创建出来了。让我们看下他们。
###邮箱MailBox###
Actor有一个MailBox(稍后我们会看到一个特例)。在我们的例子里,每个老师都有一个邮箱(mailbox)。老师需要检查邮箱(mailbox)并且处理消息。在Actor的世界里,是另一种样子-邮箱(mailbox),当它有机会它会使用Actor来完成它的工作。
邮箱维护一个先入先出的队列来保存和处理消息- 跟我们常规的收件箱有点不一样,常规的收件箱总是最新的邮件在最上面。
###现在,分发者 dispatcher###
分发者做的事很有趣。表面上看,分发者只是从ActorRef拿到消息然后将消息发给MailBox。但是在这个场景里有个很神奇的事情:
分发者包装了ExecutorService(ForkJoinPool或者ThreadPoolExecutor)。 它用这个ExecutorService来执行MailBox。
看一下这个Dispathcer里的片断:
protected[akka] override def registerForExecution(mbox: Mailbox, ...): Boolean = { ... try { executorService execute mbox ... }
###什么?你说你执行MailBox?###
是的。我们已经看到了MailBox将所有消息维护在一个队列里。当Executor运行MailBox时,MailBox必须是一个线程(Thread)。就是这样,这就是MailBox的声明和构造函数。
这里是Mailbox的签名
private[akka] abstract class Mailbox(val messageQueue: MessageQueue) extends SystemMessageQueue with Runnable
##TEACHER ACTOR##
MailBox,当它的run方法被调用时,从队列里获取一条消息并把它发给Actor来处理。
在你将消息告知(tell)ActorRef的时候一定会调用到目标Actor的receive方法。
这里的TeacherActor是个基本类,维护一个格言列表(List)并自带能处理消息的方法receive。
看下这里:
TeacherActor.scala
package me.rerun.akkanotes.messaging.actormsg1 import scala.util.Random import akka.actor.Actor import me.rerun.akkanotes.messaging.protocols.TeacherProtocol._ /* * Your Teacher Actor class. * * The class could use refinement by way of * using ActorLogging which uses the EventBus of the Actor framework * instead of the plain old System out * */ class TeacherActor extends Actor { val quotes = List( "Moderation is for cowards", "Anything worth doing is worth overdoing", "The trouble is you think you have time", "You never gonna know if you never even try") def receive = { case QuoteRequest => { import util.Random //Get a random Quote from the list and construct a response val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size))) println (quoteResponse) } } }
TeacherActor只接受一种消息格式-QuoteRequest(实际上,这个让模式匹配默认case的方式是个好实践,但这儿还是有个有趣的故事)
receive方法做的所有事是
根据模式匹配QuoteRequest
从格言的静态列表(list)中随机选取一个格言
构造一个QuoteResponse
将QuoteResponse打印到控制台
相关文章推荐
- 三角网格数据结构(2)
- Redis整合Spring结合使用缓存实例
- Struts拦截器
- 1.24 集合映射(set,list,map的使用)
- GridView中存在多行数据,如何获取数据表主键值以对某一整行数据进行编辑
- MySql 创建索引原则
- nginx初级安装配置
- 如何求解最大连续子序列的和
- c
- C#中的遍历
- vim快捷键
- VS中的快捷键快速格式化代码,使好看,整齐
- scanf()使用要点
- Python学习笔记——特殊方法
- Android控件属性方法设置
- 5.SQLite面相对象通用封装
- js执行顺序
- codeforces 522D. Closest Equals 线段树+离线
- An ebda droid中Activity启动模式详解
- 如何简单使用ngrok,将网站内网映射到外网