Подробная разница между 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