Actor 模型可用于将可变状态与外界隔离。当您有一个可变状态(例如,分配给多个并发进程的全局 ID 注册表)时,您可以将该可变状态包装在一个 Actor 中,并让客户端通过消息传递与 Actor 通信。这样,只有参与者直接访问可变状态,正如您所说,客户端消息排队等待读取和处理。消息不可变很重要。
为避免队列变满,消息处理(react
、receive
等)尽可能短很重要。长时间运行的任务应该交给其他参与者:
1. Actor A receives a message M from sender S
2. A spawns a new actor C
3. A sends (S, f(M)) to C
4. In parallel:
4a. A starts processing the next message.
4b. C does the long-running or dangerous (IO) task,
When finished, sends the result to S,
and C terminates.
过程中的一些替代方案:
- C 发
(S, result)
回给 A,A 转发给 S
- A 保留一个映射
ActorRef C => (Sender S, Message M)
,因此如果它看到 C 失败,它可以使用新的 Actor 重试处理 M。
所以回顾一下,Actor 是多线程的,以至于多个客户端可以从不同的线程向它发送多条消息,并且保证 Actor 将串行处理所有这些消息(尽管排序可以受到各种非过度严格的约束)。
请注意,虽然 Actor 的react
代码可以在多个线程上执行,但在单个给定时间点,它仅在单个给定线程上执行(您可以想象,Actor 在调度程序认为合适的情况下从一个线程跳到另一个线程,但这是技术细节)。注意:内部状态仍然不需要同步,因为 Actor保证处理消息之间的发生前语义。
并行性是通过让多个 Actor 并行工作来实现的,通常形成主管层次结构或平衡工作负载。
请注意,如果您只需要并发/异步计算,但您没有或无法摆脱全局状态,Future
那么 s 是一个更好的组合和更简单的概念。