十分钟理解Actor模式
Actor模式是一种并发模型,与另一种模型共享内存完全相反,Actor模型share nothing。所有的线程(或进程)通过消息传递的方式进行合作,这些线程(或进程)称为Actor。共享内存更适合单机多核的并发编程,而且共享带来的问题很多,编程也困难。随着多核时代和分布式系统的到来,共享模型已经不太适合并发编程,因此几十年前就已经出现的Actor模型又重新受到了人们的重视。MapReduce就是一种典型的Actor模式,而在语言级对Actor支持的编程语言Erlang又重新火了起来,Scala也提供了Actor,但是并不是在语言层面支持,Java也有第三方的Actor包,Go语言channel机制也是一种类Actor模型。
单线程编程
单核单机时代一般都是单线程编程,如果把程序比作一个工厂,那么只有一个工人,这个工人负责所有的事情,所有的原料,工具产品等都放到一个地方,因为只有一个人,因此使用一套工具就行,取原料也不用排队等。
多线程编程-共享内存
到了多核时代,有多个工人,这些工人共同使用一个仓库和车间,干什么都要排队。比如我要从一块钢料切出一块来用,我得等别人先用完。有个扳手,另一个人在用,我得等他用完。两个人都要用一个切割机从一块钢材切一块钢铁下来用,但是一个人拿到了钢材,一个人拿到了切割机,他们互相都不退让,结果谁都干不了活。

假如现在有一个任务,找100000以内的素数的个数,最多使用是个线程,如果用共享内存的方法,可以用下面的代码实现。可以看到,这些线程共享了currentNum和totalPrimeCount,对它们做操作时必须上锁。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
public class PrimeCount implements Runnable { private int currentNum = 2; //从2开始找 private int totalPrimeCount = 0; //当前已经找到的 //取一个数,不能重复,最大到100000 private int incrCurrentNum() { synchronized (this) { //如果不用锁,必然会出错。 if(currentNum > 100000) { return -1; } else { int result = currentNum; currentNum++; return result; } } } //把某个线程找到的素数个数加上 private void accPrimeCount(int count) { synchronized (this) { totalPrimeCount += count; } } @Override //一直取数并判断是否为素数,取不到了就把找到的个数累加 public void run() { int primeCount = 0; int num; while((num=incrCurrentNum()) != -1) { if(isPrime(num)) { primeCount++; } } accPrimeCount(primeCount); } private boolean isPrime(int num) { for(int i = 2; i < num; i++) { if(num % i == 0) { return false; } } return true; } @SuppressWarnings("static-access") public static void main(String[] args){ PrimeCount pc = new PrimeCount(); for(int i = 0; i < 10; i++) { new Thread(pc).start(); } try { Thread.currentThread().sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(pc.getTotalPrimeCount()); } public int getTotalPrimeCount() { return totalPrimeCount; } } |
多线程/分布式编程-Actor模型
到了分布式系统时代,工厂已经用流水线了,每个人都有明确分工,这就是Actor模式。每个线程都是一个Actor,这些Actor不共享任何内存,所有的数据都是通过消息传递的方式进行的。

如果用Actor模型实现统计素数个数,那么我们需要1个actor做原料的分发,就是提供要处理的整数,然后10个actor加工,每次从分发actor那里拿一个整数进行加工,最终把加工出来的半成品发给组装actor,组装actor把10个加工actor的结果汇总输出。
用scala实现,下面是工程的结构:

这是它们传递的消息,有一些指令,剩下的都是Int数据:

一个Actor的代码结构一般是下面这种结构,不停的接受消息并处理,没有消息就等待:

组装者代码:

分发者代码:

加工者代码:

主线程代码:

工程代码可以在附件中下载。这个代码实现的效果与前面用Java实现的是一样的,但是各个线程没有共享内存,也没有锁,这样开发起来容易,而且更适合分布式编程,因为分布式编程本身就不适合共享内存。Scala的Actor不能原生的支持分布式,但是Erlang可以,使用Erlang的Actor,分布式编程就和本地编程基本一样。但是Erlang的语法难懂,而且没有变量,几乎所有需要使用循环的地方都得用递归。
十分钟理解Actor模式的更多相关文章
- 十分钟理解Java中的动态代理
十分钟理解 Java 中的动态代理 一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...
- 十分钟理解JavaScript引擎的执行机制
关注专栏写文章 十分钟理解JavaScript引擎的执行机制 方伟景 千锋前端开发推动市场提升的学习研究者. 4 人赞同了该文章 首先,请牢记2点: JS是单线程语言 JS的Event Loop是JS ...
- 后端技术杂谈11:十分钟理解Kubernetes核心概念
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 本文转自 https://github.com/h2pl/Java-Tutorial 喜欢的 ...
- 十分钟理解Gradle
一.什么是Gradle 简单的说,Gradle是一个构建工具,它是用来帮助我们构建app的,构建包括编译.打包等过程.我们可以为Gradle指定构建规则,然后它就会根据我们的“命令”自动为我们构建ap ...
- 十分钟理解Redux核心思想,过目不忘。
白话Redux工作原理.浅显易懂. 如有纰漏或疑问,欢迎交流. Redux 约法三章 唯一数据源(state) 虽然redux中的state与react没有联系,但可以简单理解为react组件中的th ...
- Scala的Actor模式 & Akka框架
今天学Spark的时候,看到Scala的actor模式是一个加分点.所以搜了一下,看了.主要参考下面两篇文章,还没有实验,有些地方领会的不深刻: http://nxlhero.blog.51cto.c ...
- [转帖]十分钟快速理解DPI和PPI,不再傻傻分不清!
十分钟快速理解DPI和PPI,不再傻傻分不清! https://baijiahao.baidu.com/s?id=1605834796518990333&wfr=spider&for= ...
- 【NLP】十分钟快览自然语言处理学习总结
十分钟学习自然语言处理概述 作者:白宁超 2016年9月23日00:24:12 摘要:近来自然语言处理行业发展朝气蓬勃,市场应用广泛.笔者学习以来写了不少文章,文章深度层次不一,今天因为某种需要,将文 ...
- 十分钟了解分布式计算:Google Dataflow
介绍 Google Cloud Dataflow是一种构建.管理和优化复杂数据处理流水线的方法,集成了许多内部技术,如用于数据高效并行化处理的Flume和具有良好容错机制流处理的MillWheel.D ...
随机推荐
- RHEL7/CentOS7 Network Service开机无法启动的解决方法
RHEL7/CentOS7安装完成并配置好所有网络相关配置后重启机器,使用systemctl --failed检查是否有失败的服务,发现在network服务启动失败,使用systemctl statu ...
- winform 开发中 把耗时操作 封装起来 异步执行(.net 4.0)
.先定义一个 BackgroundTask.cs 代码如下: public class BackgroundTask { private static WaitDialogForm LoadingDl ...
- Visual Studio Code 基本操作 - Windows 版
1.Install the .NET SDK 2.Create app: dotnet new console -o myApp cd myApp 3.Run your app:dotnet run
- C#发送邮件(使用SSL,587端口)
static readonly string smtpServer = System.Configuration.ConfigurationManager.AppSettings["Smtp ...
- win10 数字许可证激活被 KMS激活覆盖
打开cmd(管理员身份),依次执行以下命令: slmgr/upk slmgr/ckms slmgr/rearm 重启设备后联网登录Microsoft账号,转设置-激活-疑难解答,windows会找到与 ...
- http与https通信
HTTP协议 http协议与https协议的区别 GET请求和POST请求的说明与比较 发送GET和POST请求(使用NSURLSession)
- 【ocp-12c】最新Oracle OCP-071考试题库(43题)
43.(9-2)choose three Which three tasks can be performed by DDL statements? A) preventing data retrie ...
- 【OCP认证12c题库】CUUG 071题库考试原题及答案(26)
26.choose two Examine the structure of the PRODUCTS table. Which two statements are true? A) EXPIRY_ ...
- 工作中常用Linux命令
建立软链接 ln -s 例:ln -s b a 解释:把文件夹a和文件夹b关联起来,访问文件夹a,实际访问的是问价夹b 删除软连接 rm -rf a 直接删掉a文件夹跟a和b的软连接. ...
- sql注入原理详解(一)
我们围绕以下几个方面来看这个问题: 1.什么是sql注入? 2.为什么要sql注入? 3.怎样sql注入? 1.什么是sql注入? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或 ...