首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用CompletableFutures的异步非阻塞任务

使用CompletableFutures的异步非阻塞任务
EN

Stack Overflow用户
提问于 2018-08-17 20:50:35
回答 2查看 6.3K关注 0票数 12

我需要在Java8中创建一个异步的、非阻塞的任务,我想使用CompletableFutures,但我不确定它是否满足我的需求。

为了简化这种情况,假设我们有一个API,它为用户检索一些数据,但同时想要启动一个单独的任务来执行一些操作。我不需要也不想等待这个单独的任务完成,我想立即将响应发送给用户。模拟代码中的一个示例:

代码语言:javascript
复制
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,大概是这样的:

代码语言:javascript
复制
CompletableFuture.supplyAsync(this::doSomethingNoWait)  
             .thenApply(this::logSomeMessage); 

我想知道的是,这是不是正确的方法?在doSomethingNoWait完成它必须做的事情之前,响应会返回给用户吗?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-17 22:36:29

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

CompleteableFutureFuture类的包装器,允许并行执行。让我们来看一个来自this article的例子。

代码语言:javascript
复制
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()

代码语言:javascript
复制
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);
   return "Result of the then apply";
});

应用程序将像我们前面讨论的那样执行,但一旦它完成(非异常),运行supplyAsync的当前线程将执行打印语句。

请注意,如果在完成执行后将同步转换添加到将来,则调用线程将执行该转换。如下所示:

代码语言:javascript
复制
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        throw new IllegalStateException(e);
    }
    return "Result of the asynchronous computation";
});
// Long calculations that allows the future above to finish
future.thenApply(result -> {
   System.out.println(result);
   return "Result of the then apply";
});

thenApply将在运行future.thenApply(...)的线程上运行,而不是在后台运行supplyAsync的线程上运行。

票数 12
EN

Stack Overflow用户

发布于 2019-07-12 03:28:52

只有当supplyAsync(this::doSomethingNoWait)阶段正常完成时,才会执行thenApply(this::logSomeMessage)。

你可以这样做:

代码语言:javascript
复制
CompletableFuture.supplyAsync(this::doSomethingNoWait)  
logSomeMessage()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51895840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档