Actor模型及原理
1.Actor模型
在使用Java进行并发编程时需要特别的关注锁和内存原子性等一系列线程问题,而Actor模型内部的状态由它自己维护即它内部数据只能由它自己修改(通过消息传递来进行状态修改),所以使用Actors模型进行并发编程可以很好地避免这些问题,Actor由状态(state)、行为(Behavior)和邮箱(mailBox)三部分组成
- 状态(state):Actor中的状态指的是Actor对象的变量信息,状态由Actor自己管理,避免了并发环境下的锁和内存原子性等问题
- 行为(Behavior):行为指定的是Actor中计算逻辑,通过Actor接收到消息来改变Actor的状态
- 邮箱(mailBox):邮箱是Actor和Actor之间的通信桥梁,邮箱内部通过FIFO消息队列来存储发送方Actor消息,接受方Actor从邮箱队列中获取消息
Actor的基础就是消息传递
2.使用Actor模型的好处:
- 事件模型驱动--Actor之间的通信是异步的,即使Actor在发送消息后也无需阻塞或者等待就能够处理其他事情
- 强隔离性--Actor中的方法不能由外部直接调用,所有的一切都通过消息传递进行的,从而避免了Actor之间的数据共享,想要
观察到另一个Actor的状态变化只能通过消息传递进行询问 - 位置透明--无论Actor地址是在本地还是在远程机上对于代码来说都是一样的
- 轻量性--Actor是非常轻量的计算单机,单个Actor仅占400多字节,只需少量内存就能达到高并发
3.Actor模型原理
以下通过学生与教师之间的邮件通信来理解akka中的Actor模型
学生-教师的消息传递
首先先只考虑学生单向发送消息给教师(学生--->教师),如下图:
图解:
- 学生创建一个ActorSystem
- 通过ActorSystem创建ActorRef,将QuoteRequest消息发送到ActorRef(教师代理)
- ActorRef(教师代理)消息传递到Dispatcher中
- Dispatcher依次的将消息发送到TeacherActor的邮箱中
- Dispatcher将邮箱推送到一条线程中
- 邮箱取出一条消息并委派给TeacherActor的receive方法
下面再详细的解释每一步骤
StudentSimulatorApp主程序详解:
首先StudentSimulatorApp会先启动JVM并初始化ActorSystem
如上图所示,StudentSimulatorApp的主要工作为:
- 创建ActorSystem
ActorSystem作为顶级Actor,可以创建和停止Actors,甚至可关闭整个Actor环境,
此外Actors是按层次划分的,ActorSystem就好比Java中的Object对象,Scala中的Any,
是所有Actors的根,当你通过ActorSystem的actof方法创建Actor时,实际就是在ActorSystem
下创建了一个子Actor。
可通过以下代码来初始化ActorSystemval system = ActorSystem("UniversityMessageSystem")
- 通过ActorSystem创建TeacherActor的代理(ActorRef)
看看TeacherActor的代理的创建代码
val teacherActorRef:ActorRef = system.actorOf(Props[TeacherActor])
ActorSystem通过actorOf创建Actor,但其并不返回TeacherActor而是返
回一个类型为ActorRef的东西。
ActorRef作为Actor的代理,使得客户端并不直接与Actor对话,这种Actor
模型也是为了避免TeacherActor的自定义/私有方法或变量被直接访问,所
以你最好将消息发送给ActorRef,由它去传递给目标Actor - 发送QuoteRequest消息到代理中
你只需通过!方法将QuoteReques消息发送给ActorRef(注意:ActorRef也有个tell方法,其作用就委托回调给!)
techerActorRef!QuoteRequest
等价于teacherActorRef.tell(QuoteRequest, teacherActorRef)
完整StudentSimulatorApp代码
object StudentSimulatorApp extends App{
//初始化ActorSystem
val actorSystem=ActorSystem("UniversityMessageSystem")
//构建teacherActorRef
val teacherActorRef=actorSystem.actorOf(Props[TeacherActor])
//发送消息给TeacherActor
teacherActorRef! QuoteRequest
Thread.sleep (2000)
//关闭 ActorSystem,如果不关闭JVM将不会退出
actorSystem.shutdown()
}
QuoteRequest类
object TeacherProtocol{
case class QuoteRequest() //请求
case class QuoteResponse(quoteString:String) //响应
}
Dispatcher和MailBox
ActorRef将消息处理能力委派给Dispatcher,实际上,当我们创建ActorSystem和ActorRef时,
Dispatcher和MailBox就已经被创建了
MailBox
- 每个Actor都有一个MailBox,同样,Teacher也有个MailBox,其会检查MailBox并处理消息。
MailBox内部采用的是FIFO队列来存储消息,有一点不同的是,现实中我们的最新邮件
会在邮箱的最前面。
- 每个Actor都有一个MailBox,同样,Teacher也有个MailBox,其会检查MailBox并处理消息。
Dispatcher
Dispatcher从ActorRef中获取消息并传递给MailBox,Dispatcher封装了一个线程池,之后在
线程池中执行MailBox。protected[akka] override def registerForExecution(mbox: Mailbox, ...): Boolean = {
...
try {
executorService execute mbox
...
}- 为什么能执行MailBox?
看看MailBox的实现,没错,其实现了Runnable接口
private[akka] abstract class Mailbox(val messageQueue: MessageQueue) extends SystemMessageQueue with Runnable
TeacherActor

当ActorRef发送消息调用目标Actor的reveive方法时,MailBox中的run方法被执行,接着从消息队列中取出一条消息并传递给Actor处理
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
//从list中随机选出一条消息作为回应(这里只print并没回应学生的请求)
val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size)))
println (quoteResponse)
}
}
}
TeacherActor的receive方法将匹配QuoteRequest消息
参考文章:
https://rerun.me/tag/akka/page/2/
Actor模型及原理的更多相关文章
- 以Akka为示例,介绍Actor模型
许多开发者在创建和维护多线程应用程序时经历过各种各样的问题,他们希望能在一个更高层次的抽象上进行工作,以避免直接和线程与锁打交道.为了帮助这些开发者,Arun Manivannan编写了一系列的博客帖 ...
- Actor模型原理
1.Actor模型 在使用Java进行并发编程时需要特别的关注锁和内存原子性等一系列线程问题,而Actor模型内部的状态由它自己维护即它内部数据只能由它自己修改(通过消息传递来进行状态修改),所以使用 ...
- 10 分钟了解 Actor 模型
http://www.moye.me/2016/08/14/akka-in-action_actor-model/ 过去十几年CPU一直遵循着摩尔定律发展,单核频率越来越快,但是最近这几年,摩尔定律已 ...
- .NET的Actor模型:Orleans
Orleans是微软推出的类似Scala Akka的Actor模型,Orleans是一个建立在.NET之上的,设计的目标是为了方便程序员开发需要大规模扩展的云服务, 可用于实现DDD+EventSou ...
- 大数据运算模型 MapReduce 原理
大数据运算模型 MapReduce 原理 2016-01-24 杜亦舒 MapReduce 是一个大数据集合的并行运算模型,由google提出,现在流行的hadoop中也使用了MapReduce作为计 ...
- 根据老赵轻量级Actor进行修改的Actor模型
学习了老赵轻量级Actor模型,并在实际中使用,效果不错. 老赵轻量级Actor模型: ActorLite:一个轻量级Actor模型实现(上) ActorLite:一个轻量级Actor模型实现(中) ...
- Orleans:NET的Actor模型
.NET的Actor模型:Orleans Orleans是微软推出的类似Scala Akka的Actor模型,Orleans是一个建立在.NET之上的,设计的目标是为了方便程序员开发需要大规模扩展 ...
- Actor模型[转]
原文链接:http://blog.jeoygin.org/archives/477 Actor这个模型由Carl Hewitt在1973年提出,Gul Agha在1986年发表技术报告“Actors: ...
- 终结python协程----从yield到actor模型的实现
把应用程序的代码分为多个代码块,正常情况代码自上而下顺序执行.如果代码块A运行过程中,能够切换执行代码块B,又能够从代码块B再切换回去继续执行代码块A,这就实现了协程 我们知道线程的调度(线程上下文切 ...
随机推荐
- Python HTTP库requests中文页面乱码解决方案!
http://www.cnblogs.com/bitpeng/p/4748872.html Python中文乱码,是一个很大的坑,自己不知道在这里遇到多少问题了.还好通过自己不断的总结,现在遇到乱码的 ...
- C# SqlBulkCopy数据批量入库
准备条件:20万+数据 界面设计使用的WPF. 没有对比就没有伤害,以下是我两种方式导入数据案例. 运行 结果对比: 首先使用一般sql语句导入,因为时间原因,我就没有等待程序执行完,但是我记录了大约 ...
- ES入门笔一
ES6一共有6种声明变量的方法 --ES5只有var 和 function --ES6新增了let.const.import和class四种 ES6新增let和const,用来声明变量,是对var的扩 ...
- 在Java中谈尾递归--尾递归和垃圾回收的比较(转载)
我不是故意在JAVA中谈尾递归的,因为在JAVA中谈尾递归真的是要绕好几个弯,只是我确实只有JAVA学得比较好,虽然确实C是在学校学过还考了90+,真学得没自学的JAVA好 不过也是因为要绕几个弯,所 ...
- cnblog 模板 SimpleMemory 个性化设置代码备份
/页面顶部作者名/ blogTitle h1 { font-size: 50px; margin-top: 0px; } /页面简介/ blogTitle h2 { letter-spacing: 1 ...
- Fiddler抓包工具证书安装
转自:https://www.cnblogs.com/hushaojun/p/6385947.html Fiddler证书安装(查看HTTPS) 现在很多带有比较重要信息的接口都使用了安全性更高的HT ...
- 敏捷方法之极限编程(XP)和 Scrum
区别之一: 迭代长度的不同 XP的一个Sprint的迭代长度大致为1~2周, 而Scrum的迭代长度一般为 2~ 4周. 区别之二: 在迭代中, 是否允许修改需求 XP在一个迭代中,如果一个User ...
- Executor, ExecutorService 和 Executors 间的区别与联系
UML简要类图关系: 下面详细看一下三者的区别: Executor vs ExecutorService vs Executors 正如上面所说,这三者均是 Executor 框架中的一部分.Java ...
- 基于E-R模型的关系型数据库设计方法
摘要 在管理信息系统开发中,数据库设计的目标是建立DBMS能识别的关系数据模型.而关系数据模型建立的基础是首先建立E-R模型,通过E-R模型才能转换为关系数据模型.如何建立E-R模型以及如何将E-R模 ...
- How nginx "location if" works
Nginx's if directive does have some weirdness in practice. And people may misuse it when they do not ...