Play 2.1或更高版本中的并发性

时间:2013-12-16 21:36:39

标签: scala playframework executioncontext

我已经阅读了一些关于如何在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。为什么?有人能解释一下幕后发生的事情吗?

2 个答案:

答案 0 :(得分:3)

Scala使用ExecutionContext进行一些异步操作(Futures,Promises)。 ExecutionContext可以被认为是一个线程池,其中Runnables可以被提交以在其中一个线程上运行。 (它不一定总是一个线程池,但它往往是)。

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

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

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

要回答您的问题,来自这两个示例的Implicits导入是隐式ExecutionContext实例,这些实例需要调用futurescheduleOnce方法。出于探索目的,使用哪一个并不重要。 scala库中的global包含(iirc)具有8个左右线程的线程池。我猜这个游戏很相似。除非你特别小心哪些线程做了什么工作,否则选择不应该影响你。

答案 1 :(得分:-2)

我猜这个差异来自“10秒”。字面上命名时间的能力并没有内置于语言中。 “seconds”隐式转换为DurationInt。