scala的actor模型如何利用C线程和本机系统线程?

时间:2014-12-31 10:45:39

标签: java multithreading scala jvm-hotspot

scala的actor模型如何使用C线程和本机系统线程? 我知道编译器是可插入的,因此scala编译器取代了java编译器。我对下一步感到困惑,并没有通过热点优化代码的中间表示(可能不如基于线程的模型有效)并转换为基于线程的机器代码和下进行。

2 个答案:

答案 0 :(得分:11)

Akka如何使用本机线程的非常粗略的图片如下。

  1. Akka Actor是由ActorSystem
  2. 实例化的对象
  3. 然后计划在Dispatcher上执行。
  4. Dispatcher最终将执行委托给某些ExecutorService
  5. DispatcherExecutorService的实际实现决定了JVM线程的创建和使用方式。默认情况下,使用基于fork-join池的执行程序服务。它是使用ForkJoinExecutorConfigurator创建的,它创建了一个工厂,反过来又创建了ExecutorService的相应实现。
  6. Fork-join池在内部创建多个Thread并使用它们来执行给定的任务。实际的执行策略并不重要;还有其他执行程序可以以不同的方式跨线程调度任务,并且Akka可以配置为使用它们而不是默认的。
  7. Thread是一个JVM级抽象,在标准库中实现。它使用绑定到本机库(用C ++或C等一些本地语言编写),它将线程管理委托给操作系统。
  8. 因此,当创建并启动Thread对象时,最终会创建并启动本机线程,此线程将执行提供给此Thread对象的代码。
  9. 以下是演员如何执行的简单图表:

    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内存模型规范,并且非常仔细编写逻辑以确保在正确的时间获取和释放所有锁,并且每个线程都运行最适合的任务。但那时你基本上都在编写自己的演员系统。