【问题标题】:Difference in definition of Actors vs Threads? [duplicate]演员与线程的定义有什么不同? [复制]
【发布时间】:2018-04-25 05:16:30
【问题描述】:

我试图了解 Actor 和线程定义的区别。有些文章说actors是轻量级线程,而另一些文章则说actors不是线程。我也明白一个线程可以运行多个参与者。我对如何准确区分演员和线程感到困惑。请帮我理解谢谢!

【问题讨论】:

  • 我注意到您的问题仍然是“开放的”:您没有接受答案。请查看并决定是否要accept 回答。或者让我知道我是否可以做些什么来增强我的输入以使其被接受。接受有助于未来的读者确定问题是否得到解决,并对花时间回答你的人表示感谢。

标签: java multithreading scala akka actor


【解决方案1】:

ActorThreads 相比处于更高的抽象级别。

Thread 是 JVM 概念,而 Actor 是在 JVM 中运行的普通 java 类,因此问题不在于 Actor vs线程,更多的是关于Actor 如何使用线程

什么是演员?

在一个非常简单的级别上,Actor 是一个接收消息的实体,一次接收一个消息,并对这些消息做出反应。

Actor 如何使用线程?

当Actor收到消息时,它会执行一些动作作为响应。 action 代码如何在 JVM 中运行?同样,如果您简化情况,您可以想象 Action 在当前线程上执行 action 任务。此外,Actor 可能决定在线程池上执行 action 任务。只要 Actor 确保一次只处理一条消息,这并不重要。

【讨论】:

    【解决方案2】:

    我正在尝试理解 Actor 和线程定义的区别。

    老实说,他们真的没有太多的关系,所以很难谈论他们的区别。这就像在谈论丰田凯美瑞和蓝色之间的区别。

    Actor 是一个自包含、封装的实体,它与其他自包含、封装的实体完全通过发送消息进行通信。

    现在,如果这听起来完全对你来说就像对象的定义,那么你是对的! Actors 和 Objects 之间有着深厚的联系:计算的 Actor 模型是由 Carl Hewitt 构思的,部分基于早期 Smalltalks 的消息导向执行(Smalltalk-71,Smalltalk-72)。 Alan Kay 反过来引用 PLANNER 的目标导向执行作为对 Smalltalk 的消息导向执行的重大影响……反过来,PLANNER 是由 Carl Hewitt 设计的。 (PLANNER 也是 Prolog 的前身,而 Prolog 又是 Erlang 的前身;Erlang 基于 Prolog,最初是作为 Prolog 中的一个库,第一个实现是用 Prolog 编写的。)此外,Carl Hewitt 和 Alan Kay引用 Vint Cerf 和 Bob Kahn 早期关于后来成为互联网的工作作为灵感,他们两人都深受大自然的启发,Carl Hewitt 的物理学和 Alan Kay 的微生物学。因此,深层联系和相似之处也就不足为奇了。

    Actors 和 Objects 几乎是一回事。我们通常期望面向对象系统中的消息发送是同步的、瞬时的、可靠的和有序的,而对于 Actors 则不存在这样的保证。这是 Actor 和 Object 之间的主要区别:Actor 是消息可能会丢失、重新排序、需要很长时间并且是异步的对象。 (唯一的保证是消息可能会被传递最多一次。)此外,消息的接收者通常没有对发送者的隐式引用,所以如果接收者想要回复消息,发件人需要将自己的引用与消息一起传递(与典型的面向对象系统不同,我总是可以return 给发件人一些东西)。

    Actor 可以做三件事,正是这三件事,仅此而已:

    1. 创建新的演员
    2. 将消息发送到它已经知道的 Actor 的地址(即它创建的 Actor 的地址,以及它在消息中发送的地址)
    3. 指定如何处理下一条消息(这本质上是如何为可变状态建模)

    请注意,为了向 Actor 发送消息,您需要拥有 Actor 的地址。您只能向地址发送消息。一个Actor可能有多个地址,多个Actor可能隐藏在一个地址后面。地址是不可伪造的,你不能自己构建一个,你必须把它交给你。 (这是与 C 中的指针的一个重要区别,更像是 Java 中的对象引用。)

    在 Microsoft 的 Channel9 社区网站上有一段非常精彩的视频,内容是 Carl Hewitt 本人和 Erik Meijer 之间关于演员的白板会议:Hewitt, Meijer and Szyperski: The Actor Model (everything you wanted to know, but were afraid to ask)。它以通俗易懂的方式解释了 Actor 背后的基本思想以及 Actor 的基本公理。

    Carl Hewitt 还应邀在斯坦福大学的 EE380 计算机系统座谈会上发表演讲,他在会上谈到了 How to Program the Many Cores For Inconsistency Robustness,包括对 Actors 的介绍。

    线程,OTOH 只是执行链。它们本质上只是一个指令指针和一个调用堆栈。特别是,线程没有(它们自己的)内存。一个进程的所有线程共享相同的内存。这意味着除其他外,单个行为不端的线程可能会使进程的所有个线程崩溃,并且必须仔细控制对该共享内存的所有访问。

    有些文章说actors是轻量级线程,而另一些文章则说actors不是线程。我也明白一个线程可以运行多个actor。

    您将 Actor 的概念与可能的实现混淆了。

    Actor 在现有环境中的一个非常简单的实现是让每个 Actor 成为一个进程。例如,这就是 BEAM(Erlang 的主要实现)的工作原理。这是可行的,因为在 BEAM 上,流程非常便宜且轻量级;一个进程仅重300 Byte左右,10年前一台便宜的32位单核笔记本电脑上可以有上千万个进程。这适用于 Windows 进程,例如,它们要贵得多

    还有一个在 JVM 上的 Erlang 实现(称为 Erjang),它使用 Kilim,这是一个在 JVM 上使用字节码重写的极其轻量级的 Actor 的实现。 (请注意,Erjang 和 Kilim 似乎都死了。)

    如果你想在线程上实现Actor,你会遇到一个问题,即Actor是完全隔离的,而线程是完全共享的。因此,您需要以某种方式提供这种隔离。

    在 JVM 等系统上实现 Actor 的常用方法是将 Actor 实现为对象,然后安排它们在线程池上运行以获取异步属性。这就是 Akka 的工作原理。

    【讨论】:

      【解决方案3】:

      线程是一个“活动序列”——独立于特定对象。它可以执行属于任意对象的代码。

      而演员是关于“拥有”自己的“活动序列”的特定对象。但请注意,这个演员序列不一定是一个线程。从相反的方面来说!

      从实现方面来看,可以使用一个线程来驱动多个actor对象。

      【讨论】:

      • 但是,如果我使用线程 pool 来实现 Actor,而不是让每个 Actor 在其自己的私有线程中运行呢?在这种情况下,任何参与者都不会“拥有”自己的线程。
      • 整个想法是演员不拥有线程。因为线太重了。你想在你的系统中使用数百万个演员!
      • 没错,但是您将线程定义为活动序列,然后您说Actor拥有自己的活动序列。我只是想以菜鸟阅读的方式阅读您的文本:菜鸟可能会认为您说过 Actor 必须拥有自己的线程。
      • 我明白了。我相应地更新了答案。
      【解决方案4】:

      我强烈建议先通读官方文档: https://doc.akka.io/docs/akka/current/scala/general/actors.html

      在幕后 Akka 将在一组真实线程上运行一组 Actor,通常许多 Actor 共享一个线程,并且随后对一个 Actor 的调用可能最终在不同线程上处理。 Akka 确保此实现细节不会影响处理 actor 状态的单线程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-28
        • 1970-01-01
        • 1970-01-01
        • 2012-06-13
        • 2012-11-05
        • 2016-07-24
        • 1970-01-01
        • 2010-12-04
        相关资源
        最近更新 更多