我一直在用 Java 开发 Rest API。我想将它们转换为异步。我看到的两个选项是 DeferredResult 和 CompletableFeature。
我似乎没有发现这两者之间的区别,以及何时选择另一个。
任何实时示例将不胜感激。
最佳答案
DeferredResult
是 spring 类,它只是结果的容器(顾名思义),因此我们需要显式使用某种线程池(ForkJoinPool for示例)异步运行我们的处理。 CompletableFuture 是 java.util.concurrent 的一部分,允许异步运行处理。它实现了Future,基本上具有编写、组合和执行异步计算步骤的能力。
两个选项的简单示例:
@GetMapping(value = "/deferredResult")
public DeferredResult<Boolean> useDeferredResult() {
DeferredResult<Boolean> deferredResult = new DeferredResult<>();
deferredResult.onCompletion(() -> logResult((Boolean)deferredResult.getResult()));
ForkJoinPool.commonPool().submit(() -> {
deferredResult.setResult(processRequest());
});
return deferredResult;
}
@GetMapping(value = "/completableFuture")
public CompletableFuture<Boolean> useCompletableFuture() {
return CompletableFuture.supplyAsync(this::processRequest)
.thenApplyAsync(this::logResult);
}
private boolean logResult(Boolean result) {
System.out.println("Result: " + result);
return true;
}
private boolean processRequest() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
注释:
- 默认情况下,Spring 将执行
CompletableFuture
操作ForkJoinPool
(可配置)。 - 在
DeferredResult
的情况下,logResult
将由 servlet 容器(例如 Tomcat)工作线程执行 - 不一定是一开始就收到请求的线程。 - 你可以(虽然我没有看到任何
原因)使用
CompletableFuture
异步运行处理并且 返回DeferredResult
。 - 使用
DeferredResult
,您可以注册更多回调,例如onCompleted
- 例如onError
等。See here . CompletableFuture
有很多用于编写操作的选项。 See here .
恕我直言,CompletableFuture
更优雅并且具有更多功能。
此外,here您有一个工作示例项目。
关于java - DeferedResult 和 CompletableFuture 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56382287/