我试图理解演员(Actors)和线程(Threads)的定义差异。一些文章称演员是轻量级线程,而其他文章则指出演员不是线程。我也知道一个线程可以运行多个演员。我对如何准确区分演员和线程感到困惑。请帮助我理解,谢谢!
我试图理解演员(Actors)和线程(Threads)的定义差异。一些文章称演员是轻量级线程,而其他文章则指出演员不是线程。我也知道一个线程可以运行多个演员。我对如何准确区分演员和线程感到困惑。请帮助我理解,谢谢!
Actor比Thread的抽象级别更高。
Thread是JVM的概念,而Actor是在JVM中运行的普通Java类,因此问题不是Actor vs Thread,而更多地关于Actor如何使用Threads。
什么是Actor?
简单来说,Actor是一个实体,只接收一条消息,并对这些消息做出反应。
Actor如何使用Threads?
当Actor接收到一条message时,它会执行一些action。Action代码如何在JVM中运行?如果您简化情况,可以想象Action在当前线程上执行action任务,也可能是Actor决定在线程池上执行action任务。无论怎样,只要确保每次只处理一条消息即可。
相比之下,线程只是执行的串。它们本质上只有一个指令指针和一个调用堆栈。特别地,线程没有内存(自己的内存)。进程的所有线程共享同一块内存。这意味着,除其他外,单个行为不良的线程可以使进程中的所有线程崩溃,并且对该共享内存的所有访问都必须进行精细控制。
一些文章说演员是轻量级线程,而另一些文章则说明演员不是线程。我也明白,一个线程可以运行多个演员。
你混淆了Actor的概念和可能的实现方式。
在现有环境中实现Actor的一个非常简单的方法是将每个Actor作为进程。例如,这就是BEAM(Erlang的主要实现)的工作原理。这是可行的,因为在BEAM上,进程非常便宜且轻量级;一个进程仅重约300字节,在10年前的廉价32位单核笔记本电脑上可以有数千万个进程。但是,对于Windows进程等更昂贵的进程来说,这种方式是不可行的。
还有一种在JVM上实现Erlang的方法(称为Erjang),它使用了Kilim,在JVM上使用字节码重写实现极轻量级Actor。(请注意,Erjang和Kilim似乎都已经停止更新。)
如果想要在线程上实现Actor,则存在这样一个问题:演员完全是隔离的,而线程是完全共享的。因此,您需要以某种方式提供此隔离。
在诸如JVM之类的系统上实现Actor的一种常见方法是将Actor实现为对象,然后将其调度到线程池中以获得异步属性。这就是Akka的工作方式。
线程是一种“活动序列”,与特定对象无关。它可以执行属于任意对象的代码。
而演员则涉及到一个特定对象,该对象“拥有”自己的“活动序列”。但请注意,这个演员序列不一定是线程。相反!
从实现方面来看,可以使用一个线程驱动多个演员对象。