一、为什么当代系统需要新的编程模型
- 对象只能在单线程的条件下保持封装性,多线程往往会导致内部状态的破坏。每一个不变性都可能会被两个竞争的线程破坏。
- 锁是低效的,而且还会带来死锁这一问题。
- 锁主要是本地使用的,集群化使用,会有限制。
- 多线程下数据可见性是一个不好处理的事情,什么情况下用volatile,什么情况下不用,比较难掌握。
- 多线程下异常捕获复杂,错误恢复复杂。
二、Actor
-
通过消息交互,返回值也通过消息返回。
-
不存在锁的情况,因为只有通过消息才可以修改actor的状态,由于只是用来调度actor,所以有可以有数百万个actor存在。
-
通过消息来传递错误,错误是领域中的一部分。
-
akka是通过树形结构组织actor的,所以会有父子actor存在,父actor是子actor的监督者,可以停止和关停子actor,子actor不可以自己关停自己。
-
如果想让任务拆分的更细致,可以创建子actor;一个actor要处理多个任务,可以把任务拆分成单独的子任务然后创建子actor。
-
一个actor system内的actor共享调度服务、配置信息、以及日志处理,一般情况下一个jvm创建一个actor system就可以了,当然创建多个也没问题。
-
actor之间传递的变量最好是不可变的,可用不可变消息来实现;
-
Akka actor执行方式:
三、简单示例
-
actors
1.1. Greeter:- 命令:接受向别人Greet的命令;
- 响应:通过Greeted确认greeting已经发生过了;
1.2. GreeterBot:接受Greeter的响应,发送额外greeting msg的数量以及收集响应直到消息数量达到最大值;
1.3. GreeterMain:启动的actor; -
使用actor模型的好处
2.1. 事件驱动模型:actor直接通过发送消息来进行沟通,actor之间的同学是异步的,不需要block等待响应;
2.2. 强隔离策略:actors没有提供像java object那样的api去访问object的属性和方法,actor访问另一个actor的状态数据,必须通过发送消息类进行。
2.3. 位置透明的:系统是通过factory创建的actor返回的是actor的实例引用。所以可以在任何地方启动、停止、重启以进行扩展和伸缩;
2.4. 轻量级的:每个actor实例只包含几百字节的数据,一个app可以包含数百万个actor; -
消息
3.1. Greet:发送给Greeter actor去做greet的命令;
3.2. Greeted:来自于Greeter的响应,已确认greeting发生过;
3.3. SayHello:命令GreeterMain启动greeting流程; -
整体结构
-
实例源码:https://developer.lightbend.com/guides/akka-quickstart-java/