你会使用thenCompose
当你有一个返回 a 的操作时CompletionStage
and thenApply
当你的操作不返回CompletionStage
。 -> 这是在thenApply 与 thenCompose https://stackoverflow.com/questions/43019126/completablefuture-thenapply-vs-thencompose
但是,那Async
的变种CompletionStage
接口有细微的差别和罕见的用例。
让我们考虑一下这个例子:
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
不会影响原始 future 的完成状态,与非异步变体相比,非异步变体确实会影响 future 的完成状态CompletionStage
.
用例:
thenCompose
你可能会thenCompose
当您有 2 个需要顺序执行的异步操作时:
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));
}
您只能在插入记录后检索该记录。
Async
的变种thenXXXX
methods
想象一下,您有一个允许用户自行注册的应用程序,注册后他们将收到一封确认电子邮件以确认其帐户。
如果邮件服务器停机或者需要很长时间才能撰写电子邮件或执行其他检查,您不希望用户永远等待。
然后你会使用thenApplyAsync
触发发送电子邮件逻辑,因为它对您的系统并不重要。用户可以随时返回并说“再给我发送一封电子邮件”
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));
}
注册完成后,您的系统将在此处做出响应,但不会等待电子邮件发送,从而提高系统的响应能力。
到目前为止我发现的用例Async
变体很少,但确实存在。