我需要在Java 8中创建一个异步的非阻塞任务,我想使用CompletableFutures,但不确定它是否满足我的需求。
为简化这种情况,假设我们有一个API,可以为用户检索一些数据,但同时希望启动一个单独的任务来执行一些操作。我不需要也不想等待此单独的任务完成,我想立即将响应发送给用户。模拟代码中的一个示例:
public Response doSomething(params) {
Object data = retrieveSomeData(params);
// I don't want to wait for this to finish, I don't care if it succeeds or not
doSomethingNoWait(data);
return new Response(data);
}
我正在看CompletableFutures,就像这样:
CompletableFuture.supplyAsync(this::doSomethingNoWait)
.thenApply(this::logSomeMessage);
我想知道这是否是正确的方法?在doSomethingNoWait完成响应之前,响应是否会返回给用户?
谢谢!
答案 0 :(得分:3)
很好的问题。是的,CompleteableFuture
非常适合您的需求!让我们进一步研究该类的功能。
CompleteableFuture
是Future
类的包装,并允许并行执行。让我们看一下this article中的示例。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "Result of the asynchronous computation";
});
在上面的示例中,程序将异步启动CompletableFuture
,并且新线程将在后台休眠。如果我们添加如下所示的.thenApply()
:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "Result of the asynchronous computation";
}).thenApply(result -> {
System.out.println(result);
});
应用程序将像我们之前讨论的那样执行,但是一旦完成(非异常),调用线程将执行print语句。如果不想在thenApply()
完成时强制调用线程处理CompletableFuture
代码块,请改用thenApplyAsync
。
答案 1 :(得分:0)
“ thenApply(this :: logSomeMessage)”仅在“ supplyAsync(this :: doSomethingNoWait)”阶段正常完成时才会执行。
您可以改为:
CompletableFuture.supplyAsync(this::doSomethingNoWait)
logSomeMessage()