Подтвердить что ты не робот

Детальная разница между Java8 ForkJoinPool и Executors.newWorkStealingPool?

Какова разница между уровнями при использовании:

ForkJoinPool = new ForkJoinPool(X);

и

ExecutorService ex = Executors.neWorkStealingPool(X);

Где X - желаемый уровень parallelism i.e потоки выполняются..

В соответствии с документами я нашел их похожими. Также скажите, какой из них более уместен и безопасен в любых обычных целях. У меня есть 130 миллионов записей для записи в BufferedWriter и Сортировка их, используя Unix sort by 1st column.

Также дайте мне знать, сколько потоков нужно сохранить, если это возможно.

Примечание. Моя система имеет 8 основных процессоров и 32 ГБ ОЗУ.

4b9b3361

Ответ 1

Кража работы - это метод, используемый современными пулами потоков, чтобы уменьшить конфликт в рабочей очереди.

Классический threadpool имеет одну очередь, и каждый поток потока-потока блокирует очередь, деактивирует задачу и затем разблокирует очередь. если задачи короткие, и их много, в очереди много споров. использование незаблокированной очереди действительно помогает здесь, но не решает проблему полностью.

Современные пулы потоков используют кражу работы - каждый поток имеет свою очередь. когда поток threadpool создает задачу - он помещает его в свою очередь. когда поток threadpool хочет отменить задачу - сначала пытается отменить задачу из своей очереди, а если ее нет - она ​​ "крадет" работу из других очередей потоков. это действительно уменьшает конкуренцию theradpool и улучшает производительность.

newWorkStealingPool создает пул потоков, использующий работу, с количеством потоков в виде числа процессоров.

newWorkStealingPool представляет новую проблему. если у меня есть четыре логических ядра, тогда у пула будет всего четыре потока. если мой блок задач - например, на синхронном IO - я недостаточно использую свои процессоры. я хочу четыре потока активных в в любой момент времени, например - четыре потока, которые шифруют AES и еще 140 потоков, которые ждут завершения ввода-вывода.

это то, что предоставляет ForkJoinPool - если ваша задача порождает новые задачи и эта задача ждет их завершения - пул будет вводить новые активные потоки, чтобы насытить CPU. стоит упомянуть, что ForkJoinPool также использует кражу работы.

какой из них использовать? если вы работаете с моделью fork-join или знаете, что ваши задачи блокированы на неопределенный срок, используйте ForkJoinPool. если ваши задачи короткие и в основном связаны с процессором, используйте newWorkStealingPool.

и после того, как все сказано, современные приложения, как правило, используют пул потоков с количеством доступных процессоров и используют асинхронные IO и блокировки-контейнеры, чтобы предотвращать блокировку. это (обычно) дает лучшую производительность.

Ответ 2

newWorkStealingPool - более высокий уровень абстракции для ForkJoinPool.

Если вы посмотрите на реализацию jvm Oracle, это просто предварительно сконфигурированный ForkJoinPool: public static ExecutorService newWorkStealingPool() { return new ForkJoinPool (Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); } К сожалению, глядя на реализацию, это не правильный способ понять цель класса. Также кредит на: https://dzone.com/articles/diving-into-java-8s-newworkstealingpools

Ответ 3

Это всего лишь абстракция для Fork/Join Framework...

/**
* Creates a work-stealing thread pool using all
* {@link Runtime#availableProcessors available processors}
* as its target parallelism level.
* @return the newly created thread pool
* @see #newWorkStealingPool(int)
* @since 1.8
*/
public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool(Runtime.getRuntime().availableProcessors(),
                            ForkJoinPool.defaultForkJoinWorkerThreadFactory,
                            null, true);
}