- Actor模型在本质上是一种 计算模型 ,基本的计算单元称为Actor,在Actor模型中,所有的计算都在Actor中执行
- 在面向对象编程里,一切都是对象,在Actor模型里, 一切都是Actor ,并且Actor之间是 完全隔离 的,不会共享任何变量
- Java本身并不支持Actor模型,如果需要在 Java 里使用Actor模型,需要借助第三方类库,比较完备的是 Akka
Hello Actor
public class HelloActor extends UntypedAbstractActor { // 该Actor在收到消息message后,会打印Hello message @Override public void onReceive(Object message) throws Throwable { System.out.printf("Hello %s%n", message); } public static void main(String[] args) { // 创建Actor系统,Actor不能脱离ActorSystem存在 ActorSystem system = ActorSystem.create("HelloSystem"); // 创建HelloActor ActorRef actorRef = system.actorOf(Props.create(HelloActor.class)); // 发送消息给HelloActor actorRef.tell("Actor", ActorRef.noSender()); } }
消息 VS 对象方法
-
Actor模型是 完全异步
的,而对象方法调用是 同步
的
- Actor内部的工作模式可类比成 只有一个消费者线程的生产者-消费者模式
- 在Actor模型中,发送消息仅仅是把消息发生出去而已,接收消息的Actor在接收到消息后,也不会立马处理
-
并发计算 + 分布式计算
- 调用对象方法,需要持有对象的引用,并且所有的对象都必须在同一个进程中
-
在Actor中发送消息,只需要知道对方的地址即可
- 发送消息和接收消息的Actor可以不在一个进程中,也可以不在同一台机器上
- 因此Actor模型不但适用于并发计算,也适用于分布式计算
Actor的规范定义
-
Actor是一种 基础的计算单元
,具体来讲包括三部分能力
- 处理能力 :处理接收到的消息
- 存储能力 :Actor可以存储自己的内部状态,并且内部状态在不同Actor之间是绝对隔绝的
- 通信能力 :Actor可以和其它Actor之间通信
-
当一个Actor接收到一条消息后,该Actor可以执行三种操作
-
创建更多的Actor
- 最终会呈现出一个 树状 结构
- 发消息给其它Actor
-
确定如何处理 下一条
消息
- Actor具备存储能力,有自己的内部状态,可以将Actor看作一个 状态机
- 可以把Actor处理消息看作触发状态机的状态变化
- 在Actor模型里,由于是 单线程 处理的,所以在确定下一条消息如何处理是 不存在竟态条件问题 的
-
创建更多的Actor
累加器
public class CounterActor extends UntypedAbstractActor { private int counter = 0; @Override public void onReceive(Object message) throws Throwable { if (message instanceof Number) { counter += ((Number) message).intValue(); } else { System.out.println(counter); } } // 没有锁,也没有CAS,但程序是线程安全的 public static void main(String[] args) throws InterruptedException { ActorSystem system = ActorSystem.create("CounterSystem"); ExecutorService pool = Executors.newFixedThreadPool(4); ActorRef actorRef = system.actorOf(Props.create(CounterActor.class)); // 生成4*100_000个消息 for (int i = 0; i < 4; i++) { pool.execute(() -> { for (int j = 0; j < 100_000; j++) { actorRef.tell(1, ActorRef.noSender()); } }); } pool.shutdown(); // 等待actorRef处理完所有消息 TimeUnit.SECONDS.sleep(5); // 打印结果 actorRef.tell("", ActorRef.noSender()); // 400_000 } }
小结
-
Actor模型是 异步
模型
- 不保证消息百分百送达
- 不保证消息送达的顺序与发送的顺序是一致的
- 不保证消息会被百分百处理
- 实现Actor模型的厂商都在尝试解决上面三个问题,但解决得并不完美,所以使用Actor模型是有 成本 的
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Golang并发模型:并发协程的优雅退出
- go语言大并发(一)----goroutine与并发模型
- Golang并发模型:轻松入门流水线模型
- 并发编程:内存模型
- Golang CSP并发模型
- Java并发 -- CSP模型
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。