6

我已经阅读了一些关于如何在 Play 中处理并发的教程,并找到了一些示例:

异步作业

import scala.concurrent.{ExecutionContext, future}

def sendEmailAsync(from: String, to: String, subject: String, body: String) = {
  import ExecutionContext.Implicits.global // in scala.concurrent

  future {
    EmailHelper.sendEmail(from, to, subject, body)
  }
}

预定作业

import play.api.libs.concurrent.{Akka, Execution}

def sendEmailOnSchedule(from: String, to: String, subject: String, body: String) = {
  import scala.concurrent.duration._
  import Execution.Implicits.defaultContext // in play.api.libs.concurrent

  Akka.system.scheduler.scheduleOnce(10 seconds) {
    EmailHelper.sendEmail(from, to, subject, body)
  }
}

好吧,我有点困惑......第一个示例使用scala.concurrent.ExecutionContext.Implicits.global,而第二个示例使用play.api.libs.concurrent.Execution.Implicits.defaultContext. 为什么?有人可以解释一下幕后发生的事情吗?

4

2 回答 2

3

Scala 将 anExecutionContext用于一些异步事物(Futures、Promises)。一个 ExecutionContext 可以被认为是一个线程池,Runnables可以在其中提交以在其中一个线程上运行。(它不一定总是一个线程池,但它往往是)。

使用 ExecutionContext 的方式通常是将其作为implicit参数传递给将使用它的函数。你会经常看到这样的方法签名:

def doAsyncThings(args: Args)(implicit exc: ExecutionContext): Future[Result]

“doAsyncThings”方法将使用exc传入的隐式将工作放到单独的线程上。

要回答您的问题,Implicits这两个示例的导入是隐式 ExecutionContext 实例,需要调用futureandscheduleOnce方法。出于探索目的,您使用哪一个并不重要。来自 scala 库的那个global包含(iirc)一个带有 8 个左右线程的线程池。我猜这部剧也是类似的。除非您特别注意哪些线程执行哪些工作,否则选择不应该影响您。

于 2013-12-16T23:01:00.473 回答
-2

我猜差异来自“10秒”。语言中没有按字面命名时间的能力。“秒”隐式转换为 DurationInt。

于 2013-12-17T22:51:52.050 回答