Подробная разница между Java8 ForkJoinPool и исполнителями.newWorkStealingPool?
какова разница низкого уровня между использованием:
ForkJoinPool = new ForkJoinPool(X);
и
ExecutorService ex = Executors.neWorkStealingPool(X);
здесь X - желаемый уровень параллелизма i.e потоки запущены..
согласно документам, я нашел их похожими. Также скажите мне, какой из них более подходит и безопасен при любом нормальном использовании. У меня 130 миллион записей для записи в BufferedWriter и сортировки их с помощью Unix сортировки по 1-му столбцу.
также, дайте мне знать, сколько потоков, чтобы сохранить, если это возможно.
Примечание: моя система 8 процессоры и 32 ГБ ОПЕРАТИВНОЙ ПАМЯТИ.
2 ответов
work stealing-это метод, используемый современными пулами потоков для уменьшения конкуренции в рабочей очереди.
классический threadpool имеет одну очередь, и каждый поток-пул-поток блокирует очередь, dequeue задачу, а затем разблокирует очередь. если задачи короткие и их много, в очереди возникает много разногласий. использование очереди без блокировки действительно помогает здесь, но не решает проблему полностью.
современные пулы потоков используют кражу работы - каждый поток имеет свою очередь. когда поток threadpool создает задачу - он запрашивает ее в свою очередь. когда поток threadpool хочет деактивировать задачу - он сначала пытается деактивировать задачу из своей собственной очереди, и если у него нет - он "крадет" работу из других очередей потока. это действительно уменьшает конкуренцию theradpool и улучшает производительность.
newWorkStealingPool
создает workstealing-использование пула потоков с количеством потоков в качестве количества процессоров.
newWorkStealingPool
представляет новую проблему. если у меня четыре логических ядра, то пул будет иметь всего четыре потока. если мои задачи блокируются - например, на синхронном IO - я недостаточно использую свои процессоры. чего я хочу, так это четыре!--15-->активный потоки в любой момент, например-четыре потока, которые шифруют AES и еще 140 потоков, которые ждут завершения ввода-вывода.
это ForkJoinPool
обеспечивает - если ваша задача порождает новые задачи, и эта задача ждет их завершения-пул будет вводить новые активные потоки, чтобы насытить процессор. стоит отметить, что ForkJoinPool
использует кражу работы тоже.
какой из них использовать? если вы работаете с моделью fork-join или знаете, что ваши задачи блокируются бесконечно, используйте ForkJoinPool
. если ваши задачи короткие и в основном связаны с процессором, используйте newWorkStealingPool
.
и после того, как что-либо было сказано, современные приложения, как правило, используют пул потоков с количеством доступных процессоров и использовать асинхронный ввод / вывод и lock-free-контейнеры предотвратить преграждать. это (обычно) дает лучшую производительность.
newWorkStealingPool
является более высоким уровнем абстракции для ForkJoinPool
.
если вы посмотрите на реализацию Oracle jvm, это просто предварительно настроенный ForkJoinPool
:
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
К сожалению, просмотр реализации не является правильным способом для понимания цели класса.
Также кредит: https://dzone.com/articles/diving-into-java-8s-newworkstealingpools