ThreadPool (TP) и ForkJoinPool (FJ) предназначены для разных вариантов использования. Основное различие заключается в количестве очередей, используемых различными исполнителями, которые решают, какой тип задач лучше подходит для любого исполнителя.
Исполнитель FJ имеет n (он же уровень параллелизма) отдельных параллельных очередей (запросов), в то время как исполнитель TP имеет только одну параллельную очередь (эти очереди / запросы могут быть пользовательскими реализациями, не соответствующими API коллекций JDK). В результате в сценариях, где генерируется большое количество (обычно относительно коротких) задач, исполнитель FJ будет работать лучше, поскольку независимые очереди минимизируют одновременные операции, а нечастые кражи помогут с балансировкой нагрузки. В TP из-за единственной очереди будут выполняться параллельные операции каждый раз, когда работа будет отложена, и это будет действовать как относительное узкое место и ограничивать производительность.
В отличие от этого, если количество выполняемых задач относительно меньше, одна очередь в TP больше не является узким местом для производительности. Однако n-независимые очереди и относительно частые попытки кражи работы теперь станут узким местом в FJ, так как может быть много бесполезных попыток украсть работу, которые увеличивают накладные расходы.
Кроме того, алгоритм кражи работы в FJ предполагает, что (старые) задачи, украденные из очереди, будут производить достаточно параллельных задач, чтобы уменьшить количество краж. Например. в быстрой сортировке или объединенной сортировке, где более старые задачи равняются большим массивам, эти задачи будут генерировать больше задач и сохранять непустую очередь и уменьшать общее количество краж. Если это не так в данном приложении, то частые попытки кражи снова становятся узким местом. Это также отмечено в javadoc для ForkJoinPool :
этот класс предоставляет методы проверки состояния (например, getStealCount ())
которые предназначены для помощи в разработке, настройке и мониторинге
приложения fork / join.