gpt4 book ai didi

java - 如何在 play framework 2.5 中编写异步操作?

转载 作者:行者123 更新时间:2023-11-30 08:37:53 26 4
gpt4 key购买 nike

我编写了以下代码来发送电子邮件作为非阻塞操作。它不适用于超过 1 个请求。

CompletableFuture.supplyAsync(() -> 
EmailService.sendVerificationMail(appUser , mailString)).
thenApply(i -> ok("Got result: " + i));

因为 play.Promise 在 play.2.5 (java) 中被弃用。我以前的代码不支持。所以请给我适当的解决方案,使我的行为成为非阻塞的。

最佳答案

如果函数 EmailService.sendVerificationMail 是阻塞的,CompletableFuture 只会让它在调用线程上成为非阻塞。事实上它仍然阻塞在其他线程上(可能是常见的 ForkJoinPool)。

如果只有几个电子邮件任务在运行,这不是问题。但如果电子邮件任务太多(比如 100 个或更多),它们将“控制”池。这会导致“Convoy effect”,其他任务必须等待更多时间才能开始。这会严重损害服务器性能。

如果您有很多并发电子邮件任务,您可以创建自己的池来处理它们,而不是使用公共(public)池。线程池优于 fork join 池,因为它不允许工作窃取。

或者你可以找到EmailService的异步接口(interface),或者自己实现。

为了回答另一个问题,现在 Play 2.5 使用 CompletionStage 作为默认 promise 。如果您只使用 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 的网站上。

关于java - 如何在 play framework 2.5 中编写异步操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36880744/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com