ExecutionContext特征scala.concurrent.ExecutionContext.Implicits.global
的文档为:
可以简单地导入
scala.concurrent.ExecutionContext.Implicits.global
获得一个 隐式ExecutionContext
。这种全球背景是合理的 默认线程池
“合理违约”是什么意思?
答案 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 列表。