CompletableFuture |然后应用Async与thenCompose及其用例 [英] CompletableFuture | thenApplyAsync vs thenCompose and their use cases
问题描述
我试图理解CompletableFuture,并遇到了2个方法,然后是ApplyAsync然后是Make。
我试图了解这两者之间的区别。
I was trying to understand CompletableFuture, and came across 2 methods, thenApplyAsync and thenCompose. Am trying to understand the difference between these two.
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + " Printing hello");
return "Hello";
}).thenCompose((String s) -> {
return CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + " Adding abc");
return "abc "+s;});
}).thenApplyAsync((String s) -> {
System.out.println(Thread.currentThread().getName() + " Adding world");
return s + " World";
}).thenApplyAsync((String s) -> {
System.out.println(Thread.currentThread().getName() + " Adding name");
if (false) {
throw new RuntimeException("Oh no exception");
}
return s + " player!";
}).handle((String s, Throwable t) -> {
System.out.println(s != null ? s : "BLANK");
System.out.println(t != null ? t.getMessage() : "BLANK Exception");
return s != null ? s : t.getMessage();
});
我如何将这些方法解释为, thenApplyAsync
将在不同的线程中执行提供的函数并返回结果,但在内部它被包装在CompletionStage中。然而, thenCompose
将获得返回对CompletionStage的引用。
How I interpreted these methods as, thenApplyAsync
will execute the supplied function in a different thread and return a result, but internally it is wrapped inside a CompletionStage. Whereas, thenCompose
will get the return a reference to a CompletionStage.
所以在什么情况下,我会使用 thenCompose
over thenApplyAsync
?
So under what scenarios, will I use thenCompose
over thenApplyAsync
?
通过此链接,但是它讨论的是 thenApply
,这有些不同:
CompletableFuture | thenApply vs thenCompose
Went through this link, but it was talking about thenApply
, which is somewhat different:
CompletableFuture | thenApply vs thenCompose
推荐答案
当你使用 thenCompose
时当你的操作没有返回<$ c时,你有一个返回 CompletionStage
和 thenApply
的操作$ C> CompletionStage 。 - >这是在 thenApply vs thenCompose
You would use thenCompose
when you have an operation that returns a CompletionStage
and thenApply
when you have an operation that doesn't return a CompletionStage
. -> This is was is in thenApply vs thenCompose
然而 CompletionStage
界面的 Async
变体有微妙的差异和罕见的用例。
However the Async
variants of the CompletionStage
interface have subtle difference and rare use cases.
让我们考虑这个例子:
import java.util.concurrent.CompletableFuture;
public class Futures {
public static void main(String[] args) throws InterruptedException {
CompletableFuture<Void> c = CompletableFuture.runAsync(() -> {
System.out.println("run1: " + Thread.currentThread().getId());
});
c.whenComplete((r, t) -> {
System.out.println("I'm completed");
});
c.thenCompose(__ -> {
System.out.println("thenCompose1: " + Thread.currentThread().getId());
return CompletableFuture.runAsync(() -> {
System.out.println("run2: " + Thread.currentThread().getId());
});
}).thenRunAsync(() -> {
System.out.println("RunAsync1: " + Thread.currentThread().getId());
});
Thread.sleep(5000);
System.out.println("Finished");
}
}
输出类似于:
run1: 11
thenCompose1: 11
run2: 12
I'm completed
RunAsync1: 11
Finished
请注意 thenApplyAsync
与影响 CompletionStage
的完成状态的非异步变量相比,不会影响原始未来的完成状态。
Notice that thenApplyAsync
doesn't not affect the original future's completed state in contrast with the non async variants which do affect the completed state of the CompletionStage
.
当你有2个需要按顺序执行的异步操作时,你可能 thenCompose
:
You might thenCompose
when you have 2 asynchronous operations that need to be executed sequentially:
static CompletionStage<String> insert(Object database) {
throw new UnsupportedOperationException();
}
static CompletionStage<Object> get(String id) {
throw new UnsupportedOperationException();
}
public static void main(String[] args) throws InterruptedException {
Object db = new Object(); // pretend this connects to a database
CompletionStage<Object> recordInserted = insert(db).thenCompose(id -> get(id));
}
您只能在插入记录后检索记录。
You can only retrieve the record after you inserted it.
想象一下,您有一个允许用户注册的应用程序,在注册后他们会收到一封确认电子邮件以确认他们的帐户。
Imagine for a moment that you have an application that allows users to register themselves and upon registration they will receive a confirmation email to confirm their account.
如果邮件服务器关闭或者需要很长时间撰写电子邮件或执行其他检查,您不希望用户等待。
You don't want the user to be waiting for ever if the mail server is down or if it takes a long time to compose the email or perform additional checks.
您然后使用 thenApplyAsync
来启动发送电子邮件逻辑,因为它对您的系统并不重要。用户总是可以回去说给我发送另一封电子邮件
You would then use thenApplyAsync
to fire off the send email logic because it is not crucial to your system. A user can always go back and say "send me another email"
static CompletionStage<String> register(String username) {
throw new UnsupportedOperationException();
}
static void sendConfirmationEmail(String username) {
throw new UnsupportedOperationException();
}
public static void main(String[] args) throws InterruptedException {
register("user").thenAcceptAsync(username -> sendConfirmationEmail(username));
}
此处您的系统将在注册完成后作出响应,但它不会等待发送电子邮件,从而提高系统的响应能力。
Here your system will respond when the registration is complete but it will not wait for the email to be sent resulting in improved responsiveness of your system.
到目前为止,我发现异步的用例
变种很少但确实存在。
The uses cases I've found so far for the Async
variants are scarce but they do exist.
这篇关于CompletableFuture |然后应用Async与thenCompose及其用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!