Actor类是抽象类,处理消息的handleMessage方法为抽象方法,需要每个具体类来重载实现。Node代表节点,与Skynet中节点意义相同,它是一个独立的Java进程,有自己的IP和端口,Node之间通过异步的网络通信发送和接收消息。一个Node中可以运行多个Actor,一个Actor仅可与一个Node绑定。ActorSystem是Actor的管理系统...
java编程的actor模式如何实现?
Actor模型是一种常见的并发模型,它与常见的共享内存(同步锁)模型不同,它将程序分为许多独立的计算单元——Actor,每个Actor独立管理自己的资源,不同Actor之间通过消息传递来交互。它的优势在于全异步执行,避免线程阻塞,提升CPU使用率,同时异步交互也不需要考虑加锁和线程同步的问题。
Actor模型在业界有许多应用,如游戏服务器框架Skynet、编程语言Erlang等。然而,由于历史原因,在Java下的应用相对较少,知名项目为基于Scala的Akka。尽管Actor模型不是万能的,但异步编程会需要编写更多的回调代码,原本的一步需要拆分成若干步来处理,这无疑增加了代码编写复杂度。
本文旨在学习和研究,使用Java实现一个简单Actor模型,其功能模仿Skynet,支持的功能包括创建Actor、发送消息、休眠Actor以及网络通信等。
Actor是Actor模型中的核心概念,每个Actor独立管理自己的资源,并通过Message与其他Actor之间通信。每个Actor由单线程驱动,相当于Skynet中的服务,不断从mailbox(使用无界阻塞的LinkedBlockingQueue)中获取尚未处理的Message。
Actor类是抽象类,处理消息的handleMessage方法为抽象方法,需要每个具体类来重载实现。Node代表节点,与Skynet中节点意义相同,它是一个独立的Java进程,有自己的IP和端口,Node之间通过异步的网络通信发送和接收消息。一个Node中可以运行多个Actor,一个Actor仅可与一个Node绑定。
ActorSystem是Actor的管理系统,也是外部调用API的主要入口,提供主要功能:创建Actor、发送消息、休眠Actor以及网络通信等。初始化ActorSystem分为以下三步:调用conf方法读取集群配置,包括每个Node的name和address;调用bindNode方法绑定当前Node;调用start方法初始化自身,包括对定时器的初始化和Netty服务端的初始化。
创建Actor调用newActor方法,指定要创建的Actor具体类和Actor name,Actor name需Node内部唯一。创建Actor时,先绑定当前Node,调用Actor的start方法初始化,然后将name与Actor的映射关系加入到actors中。
发送消息的核心是send方法,指定目标Node name、目标Actor name、命令名和参数后发送消息,也可以把这些信息封装在Message中发出。消息的来源Node和来源Actor保存在一个ThreadLocal变量currThreadActor中,它在Actor创建时,将Actor线程与Actor绑定在一起,使得在调用send方法发送消息时,无需再显式指定来源Node和来源Actor。
当消息的目标Node与来源Node相同,直接找到对应的Actor添加消息;否则,需要通过网络通信。网络通信实际上是一个简单的RPC通信,此处使用了Netty的ObjectEncoder和ObjectDecoder进行消息的序列化和反序列化。
休眠Actor调用sleep方法实现,它制定了需要休眠的毫秒数,休眠完后回调的命令及参数。这里的sleep方法底层通过定时任务实现,添加一个TimerTask封装过期时间和回调命令及参数,待任务到期后将命令封装成Message发送给当前Actor自身。
定时器在Timer类中实现,它在start方法中启动一个线程不断轮询处理定时任务,并提供addTimeTask方法添加新的定时任务。Timer使用优先级队列作为存储定时任务的数据结构,插入任务时能达到O(logN)的时间复杂度。为性能考虑,Timer主线程非采用每隔一小段时间不断轮询的方式,而是在当前没有任务需要执行时保持阻塞。
示例程序放在test包下面,涉及的类说明如下:运行时,先启动NodeB,再启动NodeA,NodeA下面会打印带时间戳的信息,而NodeB下面会打印另外一系列信息,从日志可以看出程序确实以期望的方式运行。
总结,本文详细介绍了使用Java实现一个简单Actor模型的完整流程。尽管本文只实现了基础功能,但目的是为了深入掌握Actor模型的核心概念,作为演示和研究的用途。对于并发模型来说,原理才是主要的、相通的,语言只不过是实现的工具。相信本文也能帮助读者对Actor模型有更深入的了解。2024-08-25