Какой исполнитель лучше передать CompletableFuture SupplyAsync Executors.newFixedThreadPool(10) или новый ForkJoinPool(10)

Я использую CompletableFuture.supplyAsync, я не хочу использовать Forkjoinpool.commonpool, я хочу передать ему пул.

В настоящее время я создаю ссылку на статический пул и использую ее, потому что я не хочу создавать пул для каждого запроса.

Я хочу знать, какой из двух способов лучше.

private static ExecutorService processingPool = Executors.newFixedThreadPool(10);
CompletableFuture.supplyAsync( () -> process(),processingPool);

or

private static ForkJoinPool processingPool = new ForkJoinPool(10);
CompletableFuture.supplyAsync( () -> process(),processingPool);

Также я читал, что ForkJoinPool создает потоки в режиме демона. Я использую блокирующий вызов «.get» в конце всей обработки, чтобы объединить результаты. Итак, мой вопрос здесь в том, что в случае, если я использую forkJoinPool выше, JVM будет ждать завершения, поскольку я использовал блокирующий вызов «.get», или он выйдет, поскольку они являются потоками демона.


person Viswa Teja Kuncham    schedule 16.05.2019    source источник


Ответы (1)


Итак, мой вопрос здесь в том, что в случае, если я использую forkJoinPool выше, JVM будет ждать завершения, поскольку я использовал блокирующий вызов «.get», или он выйдет, поскольку они являются потоками демона.

Я предполагаю, что вы вызываете get() в основном потоке или в каком-то другом потоке, не являющемся демоном. В этом случае виртуальная машина не завершится до завершения вызова get(), поэтому до этого момента не имеет значения, являются ли потоки в вашем пуле потоками демона или обычными.

После get окончательных результатов, когда в вашем пуле больше нет задач для выполнения, единственная реальная проблема заключается в чистом завершении работы ВМ. Вы должны shutdown() или shutdownNow() использовать пул, и в этом случае вы не заметите никакой разницы. Однако, если вы не закроете пул, вы можете обнаружить, что версия вашей программы с фиксированным пулом потоков завершается медленно или вообще не завершается.

person John Bollinger    schedule 16.05.2019
comment
Да, я призываю войти в основной поток. Итак, вы говорите, что передача new ForkJoinPool() в SupplyAsync будет использовать потоки из вновь созданного пула, а не из общего пула. Нужно ли нам также отключать ForkJoinPool, потому что они будут правильными потоками демонов, не будут ли они убиты после завершения. В любом случае я сделаю правильное закрытие, но хочу прояснить здесь свои концепции. Я должен выключаться, когда приложение останавливается или сервер выключается, потому что это веб-приложение, и я создаю пул в статическом контексте, чтобы он не создавался для каждого вызова. - person Viswa Teja Kuncham; 17.05.2019
comment
@ViswaTejaKuncham, любой ExecutorService, который вы создаете, вы должны закрыть, когда он вам больше не нужен. Это когда вы готовитесь завершить приложение, самое позднее. - person John Bollinger; 17.05.2019