scala的actor模型如何使用C线程和本机系统线程? 我知道编译器是可插入的,因此scala编译器取代了java编译器。我对下一步感到困惑,并没有通过热点优化代码的中间表示(可能不如基于线程的模型有效)并转换为基于线程的机器代码和下进行。
答案 0 :(得分:11)
Akka如何使用本机线程的非常粗略的图片如下。
Actor
是由ActorSystem
Dispatcher
上执行。Dispatcher
最终将执行委托给某些ExecutorService
。Dispatcher
和ExecutorService
的实际实现决定了JVM线程的创建和使用方式。默认情况下,使用基于fork-join池的执行程序服务。它是使用ForkJoinExecutorConfigurator
创建的,它创建了一个工厂,反过来又创建了ExecutorService
的相应实现。Thread
并使用它们来执行给定的任务。实际的执行策略并不重要;还有其他执行程序可以以不同的方式跨线程调度任务,并且Akka可以配置为使用它们而不是默认的。Thread
是一个JVM级抽象,在标准库中实现。它使用绑定到本机库(用C ++或C等一些本地语言编写),它将线程管理委托给操作系统。Thread
对象时,最终会创建并启动本机线程,此线程将执行提供给此Thread
对象的代码。以下是演员如何执行的简单图表:
Actor -> Dispatcher -> ExecutorService ----> Thread --| |--> OS thread
|--> Thread --|native code boundary|--> OS thread
\--> Thread --| |--> OS thread
你可以看到这里有几层抽象。最重要的是ExecutorService
:它完全定义了线程实例化和这些线程上任务执行的实际策略。可以编写单线程执行程序服务(事实上,标准库中有一个),它永远不会产生额外的线程,并且可以强制Akka使用它。
actor 的中间表示(我认为你的意思是Java字节代码)不是直接优化到一个使用本机线程的代码,因为它们是完全不同的抽象级别:actor非常高 - 级别并提供有关执行顺序的大量保证,而线程非常低级,如果您希望程序正确,则必须小心使用。 Akka确保正确使用线程,因此您不必自己考虑它。
答案 1 :(得分:1)
当然,演员最终使用较低级别的工具实现,例如java.lang.Thread
(可能使用本机线程实现,尽管这是JVM实现细节),synchronized
和各种Java原子。
关键在于演员提供了一个更好的API,其中包含易于推理的保证;系统保证给定的actor一次只处理一个消息,并按顺序处理消息,几乎就好像整个actor都在一个大的synchronized
块中 - 但是比你做的那样具有更高的性能。使用actor可以实现的任何东西,可以手动执行"通过拥有一堆锁,信号量等,仔细阅读Java内存模型规范,并且非常仔细编写逻辑以确保在正确的时间获取和释放所有锁,并且每个线程都运行最适合的任务。但那时你基本上都在编写自己的演员系统。