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

标签 scala concurrency future

ExecutionContext 上的 scala.concurrent.ExecutionContext.Implicits.global 文档特征如下:

It is possible to simply import scala.concurrent.ExecutionContext.Implicits.global to obtain an implicit ExecutionContext. This global context is a reasonable default thread pool

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

最佳答案

默认

它是固定大小ThreadPool ,其线程数与机器上的处理器数相同。合理的默认值意味着它在大多数情况下对大多数事情都有好处。

什么是“好”线程池

首先,重要的是要了解您的线程数量与机器上的核心数量相同。所有其他线程都是所谓的恶魔线程,这一切都与智能排队和执行有关。(在语言/库级别)。

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

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

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

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

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

ForkJoinPool:分而治之

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

这样的例子不胜枚举。最重要的是,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 在此列出。

关于scala - scala.concurrent.ExecutionContext.Implicits.global 的行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22702844/

相关文章:

c# - 在 C# 中通过反射访问数据时的并发问题

Java 5 : java. util.concurrent.FutureTask - cancel() 和 done() 的语义

scala - Scala 集合的测试在哪里?

scala:如何避免在 try catch block 中使用可变参数

java - scala 覆盖引用内部类的 java 类方法

scala - 如何使用值降序排列我的 Spark 结果元组

java - 线性化和串行化有什么区别?

rust - 什么时候将成员值(value)从固定的 future 中移出是安全的?

scala - Scala 中的 TraversableOnce、Future 和 Option 用于理解

scala - 如何等待 Scala future 的 onSuccess 回调完成?