Если функция EmailService.sendVerificationMail
блокируется, то CompletableFuture
делает ее неблокирующей на вызывающей нити. На самом деле он по-прежнему блокирует другую нить (возможно, общий ForkJoinPool
).
Это не проблема, если работает только несколько задач электронной почты. Но если слишком много заданий электронной почты (скажем, 100 или более), они будут «доминировать» в пуле. Это приводит к «эффекту Convoy», а другим задачам приходится ждать гораздо больше времени для начала. Это может сильно повредить производительность сервера.
Если у вас есть много параллельных задач электронной почты, вы можете создать свой собственный пул, чтобы обрабатывать их, а не использовать общий пул. Пул потоков лучше, чем пул соединений fork, потому что он не позволяет краже работы.
Или вы можете найти асинхронные API EmailService
или реализовать их самостоятельно, если это возможно.
Чтобы ответить на другой вопрос, теперь Play 2.5 использует CompletionStage
для обещания по умолчанию. Он должен работать, если вы просто используете CompletionStage
.
Некоторые примеры кода здесь. Обратите внимание на использование CompletionStage
в возвращаемом типе.
public CompletionStage<Result> testAction() {
return CompletableFuture
.supplyAsync(() -> EmailService.sendVerificationMail(appUser, mailString), EmailService.getExecutor())
.thenApply(i -> ok("Got result: " + i));
}
Для получения более подробной информации, вы можете проверить Java Migration Guide на сайте Play.
Хороший способ задать вопрос: https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/ – TheGameiswar
Не могли бы вы объяснить, что случилось в моем вопросе. На самом деле это мой первый вопрос о переполнении стека. –
Вы можете получить больше внимания, если бы предоставили более подробную информацию. Подумайте о себе в обуви другого человека, который отвечает на вопросы – TheGameiswar