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

fae*_*anj 17 concurrency scala future

对于文档scala.concurrent.ExecutionContext.Implicits.global的ExecutionContext特点如下:

可以简单地导入 scala.concurrent.ExecutionContext.Implicits.global以获得隐式ExecutionContext.此全局上下文是合理的默认线程池

"合理违约"是什么意思?

fla*_*ian 25

默认

它是一个固定大小的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
}
Run Code Online (Sandbox Code Playgroud)

}

完整列表在这里.