首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果我不在中间收集,为什么sendAsync HttpClient会按顺序工作呢?

如果我不在中间收集,为什么sendAsync HttpClient会按顺序工作呢?
EN

Stack Overflow用户
提问于 2022-01-10 18:45:20
回答 1查看 288关注 0票数 1

在关于JDK11 HttpClient的教程中,使用了一个在1秒后返回HTTP 500https://httpstat.us/500?sleep=1000端点,我准备了以下代码:

代码语言:javascript
复制
HttpClient client = HttpClient.newHttpClient();

var futures = Stream.of(
        "https://httpstat.us/500?sleep=1000",
        "https://httpstat.us/500?sleep=1000",
        "https://httpstat.us/500?sleep=1000"
).map(link -> client
        .sendAsync(
                newBuilder(URI.create(link)).GET().build(),
                HttpResponse.BodyHandlers.discarding()
        ).thenApply(HttpResponse::statusCode)
).collect(Collectors.toList());

futures.stream().map(CompletableFuture::join).forEach(System.out::println);

而且效果很好。程序执行需要1.5s,所有三个调用都同时在终端中呈现输出--一切都很好。

但当我把这个改成

代码语言:javascript
复制
HttpClient client = HttpClient.newHttpClient();

Stream.of(
        "https://httpstat.us/500?sleep=1000",
        "https://httpstat.us/500?sleep=1000",
        "https://httpstat.us/500?sleep=1000"
).map(link -> client
        .sendAsync(
                newBuilder(URI.create(link)).GET().build(),
                HttpResponse.BodyHandlers.discarding()
        ).thenApply(HttpResponse::statusCode)
).map(CompletableFuture::join).forEach(System.out::println);

它似乎不再工作异步-三个500是一个接一个显示,1秒前各延迟。

为什么?我在这里错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-10 22:50:28

这是因为Java上的map方法是一个“中间操作”,因此很懒。这意味着传递给它的Function不会在流的元素上被调用,直到下游的某个部分消耗掉该元素。

在名为JavaDoc的“流作业和管道”一节中对此进行了描述(在方括号中添加了我的注释):

中间操作返回一个新流。它们总是懒惰的;执行中间操作(如filter()map() )实际上并不执行任何筛选或映射,而是创建一个新流,在遍历时,该流包含与给定谓词匹配的初始流的元素,或者在map()的情况下由给定的函数转换。在执行管道的终端操作之前,管道源的遍历不会开始。

在本例中,这意味着在消耗流之前不会发出请求。

在第一个示例中,collect()是消耗流的终端操作。结果是表示正在运行的请求的CompletableFuture对象的列表。

在第二个示例中,forEach是一个接一个地消耗流的每个元素的终端操作。因为join操作包含在该流中,所以每个join都会在元素传递到forEach之前完成。随后的元素将按顺序使用,因此,在先前的请求完成之前,甚至不会发出每个请求。

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

https://stackoverflow.com/questions/70657451

复制
相关文章

相似问题

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