具有CompletableFutures的异步非阻塞任务

时间:2018-08-17 12:50:35

标签: multithreading java-8 completable-future

我需要在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完成响应之前,响应是否会返回给用户?

谢谢!

2 个答案:

答案 0 :(得分:3)

很好的问题。是的,CompleteableFuture非常适合您的需求!让我们进一步研究该类的功能。

CompleteableFutureFuture类的包装,并允许并行执行。让我们看一下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()