简体   繁体   English

Apache NIO HttpAsyncClient是如何进行非阻塞的 HTTP Client

[英]How is Apache NIO HttpAsyncClient performing non-blocking HTTP Client

How is Apache NIO HttpAsyncClient able to wait for a remote response without blocking any thread ? Apache NIO HttpAsyncClient 如何在不阻塞任何线程的情况下等待远程响应? Does it have a way to setup a callback with the OS (I doubt so?).它是否有办法通过操作系统设置回调(我怀疑是这样?)。 Otherwise does it perform some sort of polling?否则它会执行某种轮询吗?

EDIT - THIS ANSWER IS WRONG.编辑 - 这个答案是错误的。 PLEASE IGNORE AS IT IS INCORRECT.请忽略,因为它不正确。

You did not specify a version, so I can not point you to source code.你没有指定版本,所以我不能给你指向源代码。 But to answer your question, the way that Apache does it is by returning a Future<T> .但是要回答您的问题, Apache 的方式是返回Future<T>

Take a look at this link -- https://hc.apache.org/httpcomponents-asyncclient-4.1.x/current/httpasyncclient/apidocs/org/apache/http/nio/client/HttpAsyncClient.html看看这个链接——https://hc.apache.org/httpcomponents-asyncclient-4.1.x/current/httpasynclient/apidocs/org/apache/http/nio/client/HttpAsyncClient.html

Notice how the link says nio in the package. That stands for " non-blocking IO ".请注意链接如何在 package 中显示nio 。它代表“非阻塞 IO ”。 And 9 times out of 10, that is done by doing some work with a new thread. 10 次中有 9 次是通过使用新线程完成一些工作来完成的。

This operates almost exactly like a CompletableFuture<T> from your first question .这与您的第一个问题中的CompletableFuture<T>几乎完全一样。 Long story short, the library kicks off the process in a new thread (just like CompletableFuture<T> ), stores that thread into the Future<T> , then allows you to use that Future<T> to manage that newly created thread containing your non-blocking task.长话短说,该库在一个新线程中启动进程(就像CompletableFuture<T> ),将该线程存储到Future<T>中,然后允许您使用该Future<T>来管理新创建的线程,其中包含你的非阻塞任务。 By doing this, you get to decide exactly when and where the code blocks, potentially giving you the chance to make some significant performance optimizations.通过这样做,您可以准确决定代码块的时间和位置,从而有可能让您有机会进行一些重要的性能优化。

To be more explicit, let's give a pseudocode example.为了更明确,让我们给出一个伪代码示例。 Let's say I have a method attached to an endpoint.假设我有一个连接到端点的方法。 Whenever the endpoint is hit, the method is executed.每当命中端点时,都会执行该方法。 The method takes in a single parameter --- userID .该方法采用单个参数 --- userID I then use that userID to perform 2 operations --- fetch the user's personal info, and fetch the user's suggested content.然后我使用该userID执行 2 个操作——获取用户的个人信息,并获取用户的建议内容。 I need both pieces, and neither request needs to wait for the other to finish before starting.我需要这两部分,并且两个请求都不需要等待另一个完成才能开始。 So, what I do is something like the following.所以,我所做的是类似下面的事情。

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);

}

When I call this.fetchUserInfo(userID) , my code creates a new thread, starts fetching user info on that new thread, but let's my main thread continue and kick off this.fetchRecommendedContent(userID) in the meantime.当我调用this.fetchUserInfo(userID)时,我的代码创建了一个新线程,开始在该新线程上获取用户信息,但让我的主线程继续并同时启动this.fetchRecommendedContent(userID) The 2 fetches are occurring in parallel . 2 次提取是并行发生的

However, I need both results in order to create my StoreFrontPage .但是,我需要这两个结果才能创建StoreFrontPage So, when I decided that I cannot continue any further until I have the results from both fetches, I call Future::get on each of my fetches.因此,当我决定在获得两次提取的结果之前不能继续下一步时,我对每次提取调用Future::get What this method does is merge the new thread back into my original one .此方法所做的是将新线程合并回我原来的线程 In short, it says " wait for that one thread you created to finish doing what it was doing, then output the result as a return value ".简而言之,它表示“等待您创建的那个线程完成它正在做的事情,然后 output 结果作为返回值”。

And to more explicitly answer your question, no, this tool does not require you to do anything involving callbacks or polling.为了更明确地回答你的问题,不,这个工具不需要你做任何涉及回调或轮询的事情。 All it does is give you a Future<T> and lets you decide when you need to block the thread to wait on that Future<T> to finish.它所做的只是为您提供一个Future<T>并让您决定何时需要阻塞线程以等待该Future<T>完成。

EDIT - THIS ANSWER IS WRONG.编辑 - 这个答案是错误的。 PLEASE IGNORE AS IT IS INCORRECT.请忽略,因为它不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM