什么才是真正的Actor模型

什么才是真正的Actor模型

原创 fireflyc 写程序的康德 2016-07-16

《Java并发原理无废话指南3》中表达了一个观点:Akka不是真正的Actor模型,JVM上不可能有真正的Actor模型。那么究竟什么才是真正的Acot模型?其实这个并没有准确的定义,下面我谈谈自己的看法。
Actor可以被认为是在用户空间实现的并发实体,所以它应该是应用级别的线程。如果认同这个观点那么Actor要满足的要求=操作系统对进程/线程提出的要求一样

内存结构

每个并发实体都是要有一个固定的数据结构,必须有一个容器可以保存当前所有的并发实体。这一点基本上很容易满足,Akka中Actor就是一个类,所以它的结构就是这个类的数据结构,大小也就是这个类的大小。Akka中的Dispatcher保存有所有Acotr的列表。

并发原语

操作系统的是通过临界区,锁来定义多线程共享数据模型的。在Actor中是通过消息来共享数据的。基于消息传递要求“数据只读”,你发送出去的数据再修改肯定就不对了。但是这一点在Java里面无论如何都是做不到的,你不修改变量的引用但是还可以修改变量里面的值啊,调用对象的方法。(当然你用Scala的case class用语法麻醉自己是另外的说法)

调度

这是最重要的:没有调度,并发实体根本不能称之为并发实体。操作系统中CPU是由内核管理的,调度算法是基于时间片来调任务的,内核随时可以剥夺一个任务的CPU使用权这就是“抢占”。这一点非常重要,没有这个功能就意味着调度是不公平的。一个任务耗费大量CPU会把另个一任务给饿死。但是在用户空间(应用层)很难实现这一点,毕竟CPU是不受应用程序的控制的,没有把办法剥夺。
抢占看似可有可无,但是没有它就没有“公平调度”,也就谈不上并发。(有任务撑死,有任务饿死)举个例子:

我启动了两个Actor,Acotr里面是一个死循环会疯狂的吃CPU。如果是一个可抢占的,公平的调度test1、test2比较有规律的交替(大家得到CPU的时间差不多)整理之后的输出结果

  • test1某次执行了55次,切换到test2

  • test2执行了3086次,切换到test1

  • test1执行了5058次,切换到test2

  • test2执行了1000次,切换回test1

这个输出顺序说明了Akka根本做不到公平调度,它什么也调度不了,只能等待操作系统来切换线程。所以最终调度的还是线程而不是Actor。所谓的“调度器”名存实亡。
 

如果某个Actor因为某个错误陷入死循环,疯狂的耗费CPU那么基本上整个系统就瘫痪了,其他Actor很难有机会正常工作。(不可抢占,只能坐的操作系统来切换)
我们再来看看Erlang


看不懂没关系,我同样启动了两个任务,也是会疯狂的输出test1,test2。看一下它的输出


(我要这铁棒有何用~~~~我要这变化又如何~~~)



非常均匀的任务切换,Erlang为了实现“可抢占的公平”下了很大功夫。

对于一个技术人员追求新技术是非常好的心态,但是判断对错,识别是非的能力更重要。在审视新技术的时候才是彰显开发者真正实力的时候,对底层的把握,对问题的认识和分析这些都需要强大的“理论基础”作为支撑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值