scala.concurrent.ExecutionContext.Implicits.global的行为是什么?

时间:2014-03-28 02:04:25

标签: scala concurrency future

ExecutionContext特征scala.concurrent.ExecutionContext.Implicits.global的文档为:

  

可以简单地导入   scala.concurrent.ExecutionContext.Implicits.global获得一个   隐式ExecutionContext。这种全球背景是合理的   默认线程池

“合理违约”是什么意思?

1 个答案:

答案 0 :(得分:24)

默认

它是固定大小ThreadPool,其线程与计算机上的处理器一样多。合理的默认值意味着大多数时候它对大多数事物都有好处。

什么是“好”线程池

首先,了解您只有与机器上的核心一样多的线程,这一点很重要。所有其他线程都被称为恶魔线程,所有这些都是关于排队和执行的智能(在语言/库级别)。

CachedThreadPool:许多短暂/廉价的任务

您产生的线程池类型很大程度上取决于它们要执行的操作。对于很多短期操作(比如数据库查询),你可以使用缓存的线程池。

因为每个单独的任务相对便宜但是产生一个新线程的成本很高,所以最好使用CachedThreadPool

FixedThreadPool:长时间运行/昂贵的任务

与上述相反,对于非常昂贵的操作,您可能希望限制一次运行的线程数量,原因有多种:内存,性能等。

ForkJoinPool:Divide et impera

当您需要执行非常大的计算时,这种类型的池很有用,但您可以将它分成个别工作人员可以计算的较小位。

列表一直在继续。最重要的是,Scala为您提供了以上所有内容。具体来说,如果第一个失败,Scala会尝试创建一个ForkJoinPool并默认为ThreadPoolExecutor。

try {
  new ForkJoinPool(
    desiredParallelism,
    threadFactory,
    uncaughtExceptionHandler,
    true) // Async all the way baby
} catch {
  case NonFatal(t) =>
    System.err.println("Failed to create ForkJoinPool for the default ExecutionContext, falling back to ThreadPoolExecutor")
    t.printStackTrace(System.err)
    val exec = new ThreadPoolExecutor(
      desiredParallelism,
      desiredParallelism,
      5L,
      TimeUnit.MINUTES,
      new LinkedBlockingQueue[Runnable],
      threadFactory
    )
    exec.allowCoreThreadTimeOut(true)
    exec
}

}

full 列表。