DeferedResult 和 CompletableFeature 之间的区别

use*_*629 4 java api rest multithreading asynchronous

我一直在用 Java 开发 Rest API。我想将它们转换为异步。我看到的两个选项是 DeferredResult 和 CompletableFeature。

我似乎没有找到这两者之间的区别,以及何时选择另一个。

任何实时示例将不胜感激。

Ker*_*ode 6

DeferredResultspring类,它只是结果的容器(顾名思义),因此我们需要显式使用某种线程池(例如 ForkJoinPool)来异步运行我们的处理。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;
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 默认情况下,Spring 将执行CompletableFuture以下操作 ForkJoinPool(可以配置)。
  • 在 的情况下DeferredResultlogResult将由 servlet 容器(例如 Tomcat)工作线程执行 - 不一定是一开始就收到请求的线程。
  • 您可以(虽然我没有看到任何理由)使用CompletableFuture和 return异步运行处理DeferredResult
  • DeferredResult可以注册更多回调,例如 onCompleted- 例如onError等。请参见此处
  • CompletableFuture有很多选项来组成动作。看这里

恕我直言,CompletableFuture更优雅并且具有更多功能。

另外,这里还有一个工作示例项目。