【发布时间】:2015-08-28 14:20:27
【问题描述】:
执行上下文是如何从
import scala.concurrent.ExecutionContext.Implicits.global
不同于 Play 的执行上下文:
import play.core.Execution.Implicits.{internalContext, defaultContext}
【问题讨论】:
标签: scala playframework
执行上下文是如何从
import scala.concurrent.ExecutionContext.Implicits.global
不同于 Play 的执行上下文:
import play.core.Execution.Implicits.{internalContext, defaultContext}
【问题讨论】:
标签: scala playframework
它们非常不同。
在 Play 2.3.x 及之前的版本中,play.core.Execution.Implicits.internalContext 是具有固定大小限制的 ForkJoinPool,由 Play 内部使用。您永远不应该将它用于您的应用程序代码。来自文档:
Play 内部线程池 - 这是 Play 在内部使用的。此线程池中的线程不应执行任何应用程序代码,并且不应在此线程池中执行任何阻塞。它的大小可以通过在application.conf中设置internal-threadpool-size来配置,默认为可用处理器的数量。
相反,您将使用play.api.libs.concurrent.Execution.Implicits.defaultContext,它使用ActorSystem。
在 2.4.x 中,它们都使用相同的 ActorSystem。这意味着 Akka 将在其自己的线程池中分配工作,但以您不可见的方式(配置除外)。多个 Akka actor 可以共享同一个线程。
scala.concurrent.ExecutionContext.Implicits.global 是在 Scala 标准库中定义的 ExecutionContext。这是一个特殊的ForkJoinPool,它使用blocking 方法来处理潜在的阻塞代码,以便在池中生成新线程。你真的不应该在 Play 应用程序中使用它,因为 Play 无法控制它。如果您不小心,它还可能产生 大量 线程并使用大量内存。
我在this answer 中写了更多关于scala.concurrent.ExecutionContext.Implicits.global 的文章。
【讨论】:
它们是相同的并且指向你的底层actor系统的默认调度器 Play 或 Akka 或组合应用程序。
##默认播放的上下文
play.api.libs.concurrent.Execution.Implicits.defaultContext
##Play 的内部上下文
play.core.Execution.Implicits.internalContext
##Guice 的 EC 注入
class ClassA @Inject()(config: Configuration)
(implicit ec: ExecutionContext) {
...
}
但这是不同的:
scala.concurrent.ExecutionContext.Implicits.global
还有 DB 驱动程序,例如如果你使用 slick,可能会想出自己的 Execution Context。总之,
scala.concurrent.ExecutionContext.Implicits.global,这样在高负载时可能会使用比最佳线程更多的线程,从而导致性能下降。scala.concurrent.ExecutionContext.Implicits.global。那就不用担心这是安全的。Await 未来application.conf 中定义一个新的调度程序是一种很好的方式
【讨论】: