Actors与Threads定义的区别?

时间:2017-11-12 12:33:17

标签: java multithreading scala akka actor

我试图了解Actors和线程定义的差异。有些文章称actor是轻量级线程,而其他文章则声明actor不是线程。我也明白一个线程可以运行多个actor。我很困惑如何将角色与线程完全区分开来。请帮助我理解,谢谢!

4 个答案:

答案 0 :(得分:7)

线程相比,

Actors 处于更高的抽象级别。

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

什么是演员?

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

enter image description here

Actor如何使用线程?

当Actor收到消息时,它会执行一些操作作为响应。 action 代码如何在JVM中运行?同样,如果只是这种情况,您可以在当前线程上对执行 action 任务的Action进行映像。此外, Actor 可能决定在线程池上执行 action 任务。只要 Actor 确保一次只处理一条消息,这并不重要。 enter image description here

答案 1 :(得分:3)

  

我试图了解Actors和线程定义的差异。

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

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

现在,如果这听起来 Object 的定义完全相同,那么你是对的! Actors和Objects之间存在着深刻的联系:演员模型计算由Carl Hewitt构思,部分基于早期Smalltalks的消息导向执行(Smalltalk-71,Smalltalk-72)。反过来,Alan Kay引用了PLANNER'目标导向执行对Smalltalk的消息导向执行具有重大影响...... PLANNER又由Carl Hewitt设计。 (PLANNER也是Prolog的前身,后者又是Erlang的前身; Erlang基于Prolog,最初是Prolog的一个库,第一个实现是用Prolog编写的。)另外,还有Carl Hewitt和Alan Kay引用Vint Cerf和Bob Kahn的早期工作,以后会成为互联网的灵感来源,他们都受到大自然的启发,物理学家Carl Hewitt和微生物学Alan Alan。因此,深层次的联系和相似之处并不令人惊讶。

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

一个演员可以做三件事,完全这三件事,仅此而已:

  1. 创建新演员
  2. 将消息发送到它已经知道的演员的地址(即它创建的演员的地址,以及在消息中发送的地址)
  3. 指定如何处理下一条消息(这主要是如何建模可变状态)
  4. 请注意,要向Actor发送消息,您需要拥有Actor的地址。您只能将消息发送到地址。一个Actor可能有多个地址,多个Actors可能隐藏在一个地址后面。地址是不可伪造的,你不能自己构建地址,你必须把它交给你。 (这与C中的指针有重要区别,更像是Java中的对象引用。)

    在Carl Hewitt本人和Erik Meijer之间有关于微软Channel9社区网站上的演员的白板会议(大部分)非常精彩:Hewitt, Meijer and Szyperski: The Actor Model (everything you wanted to know, but were afraid to ask)。它以其他方式解释了演员背后的基本思想以及演员的基本公理。

    还邀请Carl Hewitt在斯坦福大学的EE380计算机系统学术讨论会上发表演讲,在那里他谈到了How to Program the Many Cores For Inconsistency Robustness,其中包括对演员的介绍。

    线程,OTOH只是执行的一部分。它们本质上只是一个指令指针和一个调用堆栈。特别是,线程没有内存(自己的)。进程的所有线程共享相同的内存。这意味着,一个行为不当的线程可能会崩溃所有进程的线程,并且必须小心控制对此共享内存的所有访问。

      

    有些文章称actor是轻量级线程,而其他文章则声明actor不是线程。我也明白一个线程可以运行多个actor。

    您正在混淆Actor的概念和可能的实现。

    现有环境中Actors的一个非常简单的实现方法是使每个Actor都成为一个进程。例如,BEAM(Erlang的主要实现)是如何工作的。这是有效的,因为在BEAM上,流程非常便宜且轻巧;一个过程只重约300字节,10年前便宜的32位单核笔记本电脑上可能有数千万个进程。例如,这将 与Windows进程一起工作,更多昂贵。

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

    如果要在线程上实现Actors,则存在Actors完全隔离而Threads完全共享的问题。所以,你需要以某种方式提供这种隔离。

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

答案 2 :(得分:2)

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

  

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

答案 3 :(得分:0)

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

而演员是关于“拥有”其自己的“活动序列”的特定对象。但请注意,此actor序列不一定是线程。与此相反的!

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