Хорошо ли выделять ExecutorService для Spring Boot с Tomcat? - PullRequest
3 голосов
/ 08 марта 2019

Я видел этот код много раз, но не знаю, в чем его преимущество / недостаток.В приложениях Spring Boot я видел, как люди определяют этот bean-компонент.

@Bean
@Qualifier("heavyLoadBean")
public ExecutorService heavyLoadBean() {
    return Executors.newWorkStealingPool();
}

Затем при создании объекта CompletableFuture на сервисном слое используется этот heavyLoadBean.

public CompletionStage<T> myService() {
   return CompletableFuture.supplyAsync(() -> doingVeryBigThing(), heavyLoadBean);
}

Затем контроллерпозвоню в службу.

@GetMapping("/some/path")
public CompletionStage<SomeModel> doIt() {
   return service.myService();
}

Не вижу смысла в этом.Tomcat в Spring Boot имеет х число потоков.Все потоки используются для обработки пользовательских запросов.Какой смысл использовать здесь другой пул потоков?В любом случае пользователь ожидает, что ответ вернется.

Ответы [ 2 ]

1 голос
/ 08 марта 2019

CompletableFuture используется для асинхронной обработки задач. Предположим, что в вашем приложении, если у вас есть две задачи, независимые друг от друга, вы можете выполнять две задачи одновременно (чтобы сократить время обработки)

public CompletionStage<T> myService() {
CompletableFuture.supplyAsync(() -> doingVeryBigThing(), heavyLoadBean);
CompletableFuture.supplyAsync(() -> doingAnotherBigThing(), heavyLoadBean);
}

В приведенном выше примере doingVeryBigThing() и doingAnotherBigThing() две задачи, которые не зависят друг от друга, поэтому теперь эти две задачи будут выполняться одновременно с двумя разными потоками из heavyLoadBean пула потоков, попробуйте приведенный ниже пример, чтобы распечатать две разные имена потоков.

public CompletionStage<T> myService() {
CompletableFuture.supplyAsync(() -> System.out.println(Thread.currentThread().getName(), heavyLoadBean);
CompletableFuture.supplyAsync(() -> System.out.println(Thread.currentThread().getName(), heavyLoadBean);
}

Если вы не предоставите пул потоков, по умолчанию предоставленный Supplier будет выполнен ForkJoinPool.commonPool()

общедоступная статическая CompletableFuture supplyAsync (Поставщик)

Возвращает новое CompletableFuture, которое асинхронно завершается задачей, выполняющейся в ForkJoinPool.commonPool (), со значением, полученным путем вызова данного поставщика.

public static CompletableFuture supplyAsync (Поставщик, поставщик, Исполнитель-исполнитель)

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

0 голосов
/ 08 марта 2019

Пожалуйста, проверьте комментарии в основном посте и другие решения.Они дадут вам больше понимания Java 8 CompletableFuture.Я просто не чувствую, что был дан правильный ответ.

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

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

Исправьте меня, если я ошибаюсь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...