Apache NIO HttpAsyncClient 如何执行非阻塞 HTTP 客户端

问题描述 投票:0回答:2

Apache NIO HttpAsyncClient 如何能够等待远程响应而不阻塞任何线程?它是否有办法与操作系统设置回调(我对此表示怀疑?)。否则它会执行某种轮询吗?

java asynchronous reactive-programming nio nonblocking
2个回答
1
投票

编辑 - 这个答案是错误的。不正确请忽略。

您没有指定版本,所以我无法向您指出源代码。但要回答你的问题,Apache 的做法是返回一个

Future<T>

看看这个链接 - https://hc.apache.org/httpcomponents-asyncclient-4.1.x/current/httpasyncclient/apidocs/org/apache/http/nio/client/HttpAsyncClient.html

注意包装中的链接如何显示

nio
。这代表“非阻塞IO”。十分之九是通过使用新线程做一些工作来完成的。

这几乎与您的

第一个问题
中的CompletableFuture<T>完全相同。长话短说,库在一个新线程中启动该进程(就像
CompletableFuture<T>
一样),将该线程存储到
Future<T>
中,然后允许您使用该
Future<T>
来管理包含您的非阻塞任务。通过这样做,您可以准确决定代码阻塞的时间和位置,从而有可能使您有机会进行一些重大的性能优化。

为了更明确,让我们给出一个伪代码示例。假设我有一个附加到端点的方法。每当到达端点时,就会执行该方法。该方法接受单个参数 ---

userID
。然后,我使用该
userID
执行 2 个操作 --- 获取用户的个人信息,并获取用户的建议内容。我需要这两部分,并且两个请求都不需要等待另一个请求完成才能开始。所以,我所做的就是下面这样。

public StoreFrontPage visitStorePage(int userID)
{

    final Future<UserInfo> userInfoFuture                 = this.fetchUserInfo(userID);
    final Future<PageSuggestion> recommendedContentFuture = this.fetchRecommendedContent(userId);

    final UserInfo userInfo = userInfoFuture.get();
    final PageSuggestion recommendedContent = recommendedContentFuture.get();

    return new StoreFrontPage(userInfo, recommendedContent);

}

当我调用

this.fetchUserInfo(userID)
时,我的代码创建一个新线程,开始在该新线程上获取用户信息,但同时让我的主线程继续并启动
this.fetchRecommendedContent(userID)
。 2 次提取并行发生

但是,我需要这两个结果才能创建我的

StoreFrontPage
。因此,当我决定在获得两次提取的结果之前不能继续继续时,我会在每次提取时调用
Future::get
。这个方法的作用是将新线程合并回我原来的线程。简而言之,它表示“等待您创建的一个线程完成它正在做的事情,然后将结果作为返回值输出”。

为了更明确地回答你的问题,不,这个工具不需要你做任何涉及回调或轮询的事情。它所做的只是给您一个

Future<T>
,并让您决定何时需要阻塞线程以等待
Future<T>
完成。

编辑 - 这个答案是错误的。不正确请忽略。


0
投票

异步http客户端一启动,就会启动一个或多个线程。其中一些线程将被阻塞等待数据,但它们是客户端内部的,因此用户创建的线程都不会被阻塞。

该机制比每个请求启动一个线程要简单得多:有一种方法可以将许多套接字复用到一个对象(“选择器”)上,并进行阻塞等待以等待任何套接字准备好读取或写入:这这样,(内部)线程被阻塞,但由于它同时处理许多套接字,因此它不会被其中任何一个阻塞。也许这也有助于“无阻塞”的比喻。

© www.soinside.com 2019 - 2024. All rights reserved.