首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >thenApply和thenApplyAsync of Java CompletableFuture有什么区别?

thenApply和thenApplyAsync of Java CompletableFuture有什么区别?
EN

Stack Overflow用户
提问于 2017-11-25 18:37:44
回答 4查看 30.3K关注 0票数 79

假设我有以下代码:

代码语言:javascript
运行
复制
CompletableFuture<Integer> future  
        = CompletableFuture.supplyAsync( () -> 0);

thenApply案件:

代码语言:javascript
运行
复制
future.thenApply( x -> x + 1 )
      .thenApply( x -> x + 1 )
      .thenAccept( x -> System.out.println(x));

这里的输出是2,如果是thenApplyAsync的话

代码语言:javascript
运行
复制
future.thenApplyAsync( x -> x + 1 )   // first step
      .thenApplyAsync( x -> x + 1 )   // second step
      .thenAccept( x -> System.out.println(x)); // third step

我在这个博客中看到,每个thenApplyAsync都是在一个单独的线程中执行的,并且“同时执行”(这意味着在thenApplyAsyncs完成之前执行thenApplyAsyncs ),如果是这样的话,如果第一步没有完成,那么第二步的输入参数值是多少?

如果第二步不采取,第一步的结果将如何?第三步将采取哪一步的结果?

如果第二步必须等待第一步的结果,那么Async的意义是什么?

这里,x -> x+1只是为了说明这一点,我想知道的是在非常长的计算情况下。

EN

Stack Overflow用户

发布于 2022-09-06 08:01:03

thenApplyAsyncthenApply中,传递给这些方法的Consumer<? super T> action将被异步调用,不会阻塞指定使用者的线程。

这种差异与哪个线程负责调用方法Consumer#accept(T t)有关。

AsyncHttpClient 考虑如下所示的调用:注意下面打印的线程名。我希望它能让你弄清楚其中的区别:

代码语言:javascript
运行
复制
// running in the main method
// public static void main(String[] args) ....

CompletableFuture<Response> future =
    asyncHttpClient.prepareGet(uri).execute().toCompletableFuture();

log.info("Current Thread " + Thread.currentThread().getName());

//Prints "Current Thread main"

thenApply 将使用与完成未来相同的线程。

代码语言:javascript
运行
复制
//will use the dispatcher threads from the asyncHttpClient to call `consumer.apply`
//The thread that completed the future will be blocked by the execution of the method `Consumer#accept(T t)`.
future.thenApply(myResult -> {
    log.info("Applier Thread " + Thread.currentThread().getName());
    return myResult;
})

//Prints: "Applier Thread httpclient-dispatch-8"

thenApplyAsync 将使用执行器池中的线程.

代码语言:javascript
运行
复制
//will use the threads from the CommonPool to call `consumer.accept`
//The thread that completed the future WON'T be blocked by the execution of the method `Consumer#accept(T t)`.
future.thenApplyAsync(myResult -> {
    log.info("Applier Thread " + Thread.currentThread().getName());
    return myResult;
})

//Prints: "Applier Thread ForkJoinPool.commonPool-worker-7"

future.get() 将阻塞主线程.

代码语言:javascript
运行
复制
//If called, `.get()` may block the main thread if the CompletableFuture is not completed.
future.get();

结论

方法thenApplyAsync中的thenApplyAsync后缀意味着完成未来的线程不会被Consumer#accept(T t) method的执行所阻塞。

thenApplyAsyncthenApply的使用取决于您是否想阻止线程完成将来的工作。

票数 0
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47489338

复制
相关文章

相似问题

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