Play Framework:thread-pool-executor vs fork-join-executor

dat*_*ser 3 multithreading scala threadpool actor playframework-2.0

假设我们的控制器中有一个动作.在每个请求中,许多用户都会调用performLogin.

def performLogin( ) = {
    Async {
        // API call to the datasource1
        val id = databaseService1.getIdForUser();

        // API call to another data source different from above
        // This process depends on id returned by the call above
        val user = databaseService2.getUserGivenId(id);

        // Very CPU intensive task 
        val token = performProcess(user)

        // Very CPU intensive calculations
        val hash = encrypt(user)

        Future.successful(hash)
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道fork-join-executor的作用.基本上,从接收请求的主线程,它跨越多个工作线程,这些工作线程将工作分成几个块.最终主线程将加入这些结果并从函数返回.

另一方面,如果我选择了线程池执行器,我的理解是从线程池中选择一个线程,这个选定的线程将完成工作,然后返回线程池来听更多的工作去做.所以这里没有发生任务的细分.

在上面的代码中,fork-join执行程序的并行性在我看来是不可能的.每次调用不同的方法/函数都需要上一步的操作.如果我选择fork-join执行器来进行线程化,那对我有什么好处呢?fork-join与线程池执行器之间的上述代码执行有何不同.

谢谢

win*_*ner 6

这不是并行代码,Async调用内的所有内容都将在一个线程中运行.事实上,玩!永远不会产生新线程来响应请求 - 它是基于事件的,有一个底层线程池可以处理需要完成的任何工作.

执行者处理来自Akka演员和大多数期货(不是用Future.successful或创建的Future.failed)的工作安排.在这种情况下,每个请求将是执行程序必须安排到线程上的单独任务.

fork-join-executor取代了thread-pool-executor,因为它允许工作窃取,从而提高了效率.可以与两个执行器并行化的内容没有区别.

  • 基本上,每个线程都有自己的队列,而不是线程共享它们从中接收任务的队列。如果其队列运行try,它将从另一个线程的队列之一中窃取一半的工作(这是一个示例,工作窃取的范围比这还要广)。关于并行收集框架的[本文](http://infoscience.epfl.ch/record/150220/files/pc.pdf)是对该主题的很好阅读。 (2认同)