Ответ 1
По умолчанию
Это фиксированный размер 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
}
}
полный список.