scala.concurrent.ExecutionContext.Implicits.global的行为是什么? [英] What is the behavior of scala.concurrent.ExecutionContext.Implicits.global?
问题描述
可以简单导入
scala.concurrent.ExecutionContext.Implicits.global
以获取
隐式ExecutionContext
。这个全局上下文是一个合理的
默认线程池
合理的默认是什么意思?
默认
href =http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-> ThreadPool ,其具有与机器上的处理器一样多的线程。合理的默认意味着它在大多数时间对大多数事情有好处。
一个好线程池
首先,理解你只有与机器上的核心一样多的线程。所有其他线程都是所谓的demon线程,它是所有关于使用队列和执行的聪明(在语言/库级别)。
CachedThreadPool:Many短暂的/廉价的任务
你生成的线程池的类型很大程度上取决于它们要执行的操作。对于很多短暂的动作(比如数据库查询),你会去一个缓存线程池。
因为每个单独的任务相对便宜,但产生一个新的线程是昂贵的,则最好使用 CachedThreadPool 。
$ b
FixedThreadPool:长时间运行/昂贵的任务 $ b
与上述相反,对于非常昂贵的操作,您可能想限制一次运行的线程数量,原因如下:内存,性能等。
ForkJoinPool:Divide et impera
这种类型的池在需要执行大型计算时非常有用,将其划分为个体工作人员可以计算的更小的位。
列表继续。底线,Scala给你之间的所有上述。具体来说,Scala尝试创建一个ForkJoinPool,如果第一个失败则默认为ThreadPoolExecutor。
try {
new ForkJoinPool (
desiredParallelism,
threadFactory,
uncaughtExceptionHandler,
true)//异步所有方式baby
} catch {
case NonFatal(t)=> ;
System.err.println(无法为默认的ExecutionContext创建ForkJoinPool,回退到ThreadPoolExecutor)
t.printStackTrace(System.err)
val exec = new ThreadPoolExecutor(
requiredParallelism,
desiredParallelism,
5L,
TimeUnit.MINUTES,
new LinkedBlockingQueue [Runnable],
threadFactory
)
exec。 allowCoreThreadTimeOut(true)
exec
}
}
完整 列表。
The documentation for scala.concurrent.ExecutionContext.Implicits.global
on the ExecutionContext trait reads:
It is possible to simply import
scala.concurrent.ExecutionContext.Implicits.global
to obtain an implicitExecutionContext
. This global context is a reasonable default thread pool
What does it mean by "reasonable default"?
Default
It's a fixed size ThreadPool, which has as many threads as the processors on the machine. A reasonable default means it's good for most things most of the time.
What a "good" thread pool is
First, it's important to understand you only have as many threads as the cores on the machine. All other threads are so called demon threads and it's all about being smart with queue-ing and executing.(at language/library level).
CachedThreadPool: Many short lived/cheap tasks
The type of thread pools you spawn vastly depend on the actions they are mean to perform. For a lot of short lived actions(say database queries), you would go a with a cached thread pool.
Because each individual task is relatively cheap but spawning a new thread is expensive, you are better off with a CachedThreadPool.
FixedThreadPool: Long running/expensive tasks
In contrast with the above, for very expensive operations, you probably want to limit the amount of threads running at one time, for various reasons: memory, performance etc.
ForkJoinPool: Divide et impera
This type of pool is useful when you need to perform a very large computation, but you can divide it into smaller bits individual workers can compute.
The list goes on and on. Bottom line, Scala gives you something in between all of the above. Specifically, Scala tries to create a ForkJoinPool and defaults to a ThreadPoolExecutor if the first fails.
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
}
}
The full list here.
这篇关于scala.concurrent.ExecutionContext.Implicits.global的行为是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!