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,这就实现了协程 我们知道线程的调度(线程上下文切 ...
随机推荐
- Ocelot中文文档-Websockets
Ocelot额外支持代理websockets.这个功能在问题 212中被提出. 为了是Ocelot代理websocket,你需要做如下事情. 在你的Configure方法中,你要告知应用程序使用Web ...
- Interface Development
- FileReader读取本地文件
FileReader是一种异步读取文件机制,结合input:file可以很方便的读取本地文件. 一.input:type[file] file类型的input会渲染为一个按钮和一段文字.点击按钮可打开 ...
- C++中遍历读取数组中的元素
答案来源:https://zhidao.baidu.com/question/187071815.html 对于字符数组str[N],判断方法有以下三种: 第一种:用库函数strlen 1 len = ...
- C#语言中的XmlSerializer类的XmlSerializer.Deserialize (Stream)方法举例详解
包含由指定的 XML 文档反序列化 Stream. 命名空间: System.Xml.Serialization程序集: System.Xml(位于 System.Xml.dll) 注意: 反序 ...
- composer安装laravel指定版本
版权声明:本文为博主原创文章,未经博主允许不得转载. http://blog.csdn.net/qq_38125058/article/details/79126051 首先安装composer,附安 ...
- DDD实战进阶第一波(十):开发一般业务的大健康行业直销系统(实现经销商登录仓储与逻辑)
上一篇文章主要讲了经销商注册的仓储和领域逻辑的实现,我们先把应用服务协调完成经销商注册这部分暂停一下,后面文章统一讲. 这篇文章主要讲讲经销商登录的仓储和相关逻辑的实现. 在现代应用程序前后端分离的实 ...
- Fiddler证书安装(查看HTTPS)
现在很多带有比较重要信息的接口都使用了安全性更高的HTTPS,而Fiddler默认是抓取HTTP类型的接口,要想查看HTTPS类型接口就需要安装fiddler证书. fiddler安装教程可参考: ...
- Map集合的便利学习总结
1.Map提供了三种便利方式 1)遍历所有key. Set<K> keySet() 该方法会将当前Map中所有key存入一个Set集合后返回. 2)遍历所有的key-value对 Se ...
- SSH整合配置文件概括
配置方式一:struts.xml, applicationContext.xml(hibernate.cfg.xml配置信息写入spring配置文件中) (版本号, struts2:2.3.15; s ...