java actor模型和消息传递实现分析
Actor模型是一种基于协程的消息传递模型,在并行计算和并发的消息传递中有很好的性能表现。一般的actor模块框架提供了超轻量级的线程和工具,可以在这些线程之间进行快速、安全、零复制的消息传递。在elang,ruby,lua等语言中都是直接在VM级别支持协程,VM帮你做context的保存和恢复。而在java中,却没有内置actor模型实现,但是有几个开源框架也模拟了actor模型的实现。
基于 actor 的系统 通过实现一种消息传递 模式,使并行处理更容易编码。在此模式中,系统中的每个 actor 都可接收消息;执行该消息所表示的操作;然后将消息发送给其他 actor(包括它们自己)以执行复杂的操作序列。actor 之间的所有消息是异步的,这意味着发送者会在收到任何回复之前继续进行处理。因此,一个 actor 可能终生都陷入接收和处理消息的无限循环中。
当使用多个 actor 时,独立的活动可轻松分配到多个可并行执行消息的线程上(进而分配在多个处理器上)。一般而言,每个 actor 都在一个独立线程上处理消息。一些 actor 系统静态地向 actor 分配线程;而其他系统(比如本文中介绍的系统)则会动态地分配它们。
下面我们会分析下java中的一个actor模型框架的实现:
我们先看下elang中的actor模型的实现:
以Erlang为例子,介绍一下简单的Actor模型
1.首先建立一个Actor,在erlang中,起一个进程(这个是erlang虚拟机进程,跟os进程不同),这个进程就是actor了,可以用来接收和发送各种消息了
Pid = spawn(Mod,func,Args) %起一个进程
2.处理收到的消息
func()->
receive
{From,Msg}-> %收到一个消息
%%do something
func();
3.要对这个actor发送消息,也非常简单
Pid ! {From,Msg}
ujavaactor框架:
下面摘自ibm developer的一段介绍
μJavaActors 是 actor 系统的一个简单的 Java 实现。只有 1,200 行代码,μJavaActors 虽然很小,但很强大。在下面的练习中,您将学习如何使用 μJavaActors 动态地创建和管理 actor,将消息传送给它们。
μJavaActors 围绕 3 个核心界面而构建:
Message 是 3 个(可选的)值和一些行为的容器:source 是发送 actor。subject 是定义消息含义的字符串(也称为命令)。data 是消息的任何参数数据;通常是一个映射、列表或数组。参数可以是要处理和/或其他 actor 要与之交互的数据。subjectMatches() 检查消息主题是否与字符串或正则表达式匹配。μJavaActors 包的默认消息类是 DefaultMessage。ActorManager 拥有以下关键行为或特征:createActor() 创建一个 actor 并将它与此管理器相关联。startActor() 启动一个 actor。detachActor() 停止一个 actor 并将它与此管理器断开。send()/broadcast() 将一条消息发送给一个 actor、一组 actor、一个类别中的任何 actor 或所有 actor。在大部分程序中,只有一个 ActorManager,但如果您希望管理多个线程和/或 actor 池,也可以有多个 ActorManager。此接口的默认实现是 DefaultActorManager。Actor 具有以下关键行为或特征:name,该名称在每个 ActorManager 中必须是惟一的。category;类别是一种向一组 actor 中的一个成员发送消息的方式。一个 actor 一次只能属于一个类别。ActorManager 可以提供一个执行 actor 的线程,系统就会调用 receive()。为了保持最高效率,actor 应该迅速处理消息,而不要进入漫长的等待状态(比如等待人为输入)。willReceive() 允许 actor 过滤潜在的消息主题。peek() 允许该 actor 和其他 actor 查看是否存在挂起的消息(或许是为了选择主题)。remove() 允许该 actor 和其他 actor 删除或取消任何尚未处理的消息。getMessageCount() 允许该 actor 和其他 actor 获取挂起的消息数量。getMaxMessageCount() 允许 actor 限制支持的挂起消息数量;此方法可用于预防不受控制地发送。大部分程序都有许多 actor,这些 actor 常常具有不同的类型。actor 可在程序启动时创建或在程序执行时创建(和销毁)。本文中的 actor 包 包含一个名为 AbstractActor 的抽象类,actor 实现基于该类。12:59:38.883 T [main ] - TestActor activate: TestActor[name=common06, category=TestActor, messages=0]12:59:38.886 T [main ] - TestActor activate: TestActor[name=common05, category=TestActor, messages=0]12:59:38.887 T [main ] - TestActor activate: TestActor[name=common08, category=TestActor, messages=0]12:59:38.889 T [main ] - TestActor activate: TestActor[name=common07, category=TestActor, messages=0]12:59:38.890 T [main ] - TestActor activate: TestActor[name=common09, category=TestActor, messages=0]12:59:38.891 T [main ] - TestActor activate: TestActor[name=common00, category=TestActor, messages=0]12:59:38.892 T [main ] - TestActor activate: TestActor[name=common01, category=TestActor, messages=0]12:59:38.893 T [main ] - TestActor activate: TestActor[name=common02, category=TestActor, messages=0]12:59:38.895 T [main ] - TestActor activate: TestActor[name=common03, category=TestActor, messages=0]12:59:38.896 T [main ] - TestActor activate: TestActor[name=common04, category=TestActor, messages=0]12:59:38.897 T [main ] - TestActor activate: TestActor[name=actor24, category=default, messages=0]12:59:38.899 T [main ] - TestActor activate: TestActor[name=actor11, category=default, messages=0]12:59:38.904 T [main ] - TestActor activate: TestActor[name=actor23, category=default, messages=0]12:59:38.905 T [main ] - TestActor activate: TestActor[name=actor10, category=default, messages=0]12:59:38.906 T [main ] - TestActor activate: TestActor[name=actor22, category=default, messages=0]12:59:38.907 T [main ] - TestActor activate: TestActor[name=actor13, category=default, messages=0]12:59:38.908 T [main ] - TestActor activate: TestActor[name=actor21, category=default, messages=0]12:59:38.909 T [main ] - TestActor activate: TestActor[name=actor12, category=default, messages=0]12:59:38.910 T [main ] - TestActor activate: TestActor[name=actor20, category=default, messages=0]12:59:38.911 T [main ] - TestActor activate: TestActor[name=actor02, category=default, messages=0]12:59:38.912 T [main ] - TestActor activate: TestActor[name=actor01, category=default, messages=0]12:59:38.914 T [main ] - TestActor activate: TestActor[name=actor00, category=default, messages=0]12:59:38.915 T [main ] - TestActor activate: TestActor[name=actor19, category=default, messages=0]12:59:38.916 T [main ] - TestActor activate: TestActor[name=actor06, category=default, messages=0]12:59:38.917 T [main ] - TestActor activate: TestActor[name=actor18, category=default, messages=0]12:59:38.917 T [main ] - TestActor activate: TestActor[name=actor05, category=default, messages=0]12:59:38.918 T [main ] - TestActor activate: TestActor[name=actor04, category=default, messages=0]12:59:38.919 T [main ] - TestActor activate: TestActor[name=actor03, category=default, messages=0]12:59:38.920 T [main ] - TestActor activate: TestActor[name=actor15, category=default, messages=0]12:59:38.921 T [main ] - TestActor activate: TestActor[name=actor14, category=default, messages=0]12:59:38.922 T [main ] - TestActor activate: TestActor[name=actor09, category=default, messages=0]12:59:38.923 T [main ] - TestActor activate: TestActor[name=actor17, category=default, messages=0]12:59:38.923 T [main ] - TestActor activate: TestActor[name=actor08, category=default, messages=0]12:59:38.924 T [main ] - TestActor activate: TestActor[name=actor16, category=default, messages=0]12:59:38.925 T [main ] - TestActor activate: TestActor[name=actor07, category=default, messages=0]12:59:38.926 T [main ] - main waiting: 120...12:59:42.970 T [actor3 ] - TestActor:common06 init(4): TestActor[name=common06, category=TestActor, messages=0]12:59:43.028 T [actor2 ] - TestActor:common03 init(8): TestActor[name=common03, category=TestActor, messages=0]12:59:43.048 T [actor1 ] - TestActor:common01 init(6): TestActor[name=common01, category=TestActor, messages=0]12:59:43.054 T [actor8 ] - TestActor:common05 init(4): TestActor[name=common05, category=TestActor, messages=0]12:59:43.064 T [actor6 ] - TestActor:common09 init(8): TestActor[name=common09, category=TestActor, messages=0]12:59:43.873 T [actor0 ] - TestActor:common02 init(7): TestActor[name=common02, category=TestActor, messages=0]12:59:43.898 T [actor9 ] - TestActor:common08 init(1): TestActor[name=common08, category=TestActor, messages=0]12:59:43.993 T [actor7 ] - TestActor:common04 init(2): TestActor[name=common04, category=TestActor, messages=1]12:59:43.994 T [actor5 ] - TestActor:common00 init(1): TestActor[name=common00, category=TestActor, messages=0]12:59:43.996 W [actor2 ] - init:common03 to is null: actor512:59:44.039 W [actor8 ] - init:common05 to is null: actor912:59:44.052 W [actor1 ] - init:common01 to is null: actor912:59:44.060 T [actor4 ] - TestActor:common07 init(5): TestActor[name=common07, category=TestActor, messages=0]12:59:44.912 W [actor0 ] - init:common02 to is null: actor612:59:44.968 W [actor5 ] - init:common00 to is null: actor912:59:44.986 W [actor3 ] - init:common06 to is null: actor112:59:44.986 W [actor7 ] - init:common04 to is null: actor912:59:45.108 W [actor4 ] - init:common07 to is null: actor812:59:45.947 T [actor9 ] - TestActor:actor13 init(7): TestActor[name=actor13, category=default, messages=0]12:59:45.951 T [actor5 ] - TestActor:actor22 init(1): TestActor[name=actor22, category=default, messages=1]12:59:45.976 W [actor3 ] - init:common06 to is null: actor112:59:46.016 W [actor2 ] - init:common03 to is null: actor612:59:46.052 W [actor1 ] - init:common01 to is null: actor612:59:46.115 W [actor4 ] - init:common07 to is null: actor912:59:46.932 W [actor3 ] - init:common06 to is null: actor512:59:46.940 W [actor5 ] - init:actor22 to is null: actor312:59:47.039 T [actor7 ] - TestActor:actor24 init(8): TestActor[name=actor24, category=default, messages=1]12:59:47.042 W [actor1 ] - init:common01 to is null: actor612:59:47.059 W [actor2 ] - init:common03 to is null: actor012:59:47.904 T [actor8 ] - TestActor:actor21 init(7): TestActor[name=actor21, category=default, messages=1]12:59:47.964 T [actor3 ] - TestActor:actor10 init(4): TestActor[name=actor10, category=default, messages=0]12:59:47.988 T [actor5 ] - TestActor:actor23 init(7): TestActor[name=actor23, category=default, messages=2]12:59:48.003 W [actor6 ] - init:common09 to is null: actor312:59:48.042 W [actor1 ] - init:common01 to is null: actor612:59:48.072 W [actor2 ] - init:common03 to is null: actor812:59:48.101 W [actor4 ] - init:common07 to is null: actor612:59:48.880 W [actor8 ] - init:actor21 to is null: actor812:59:48.903 W [actor9 ] - init:actor13 to is null: actor312:59:48.952 T [main ] - main waiting: 110...12:59:49.024 W [actor2 ] - init:common03 to is null: actor312:59:49.037 W [actor6 ] - init:common09 to is null: actor912:59:49.085 W [actor4 ] - init:common07 to is null: actor6