gpt4 book ai didi

java - OkHttp 如何在不使用线程的情况下使用看似同步的 HTTP 连接执行并行 HTTP 请求?

转载 作者:太空狗 更新时间:2023-10-29 22:43:48 26 4
gpt4 key购买 nike

我用 OkHttp 做了一些性能测试图书馆,发现它很棒。它向 http://httpbin.org/delay/1 发出了 80 次请求,在我的 HTC One 手机上,它会在 4.7 秒内针对每个请求故意暂停 1 秒。我查看了代码,并试图找出为什么它如此之快。开发人员 (Square Inc) 宣传连接池和异步调用,我认为这两者都有助于实现良好的性能。

我来自 .NET 世界,在 .NET 4.5 中你有一个真正的异步 HTTP 库,它带有异步 GetResponse-method .通过在等待响应时将线程交给操作系统,您可以释放资源来启动更多 HTTP 请求或其他内容。问题是我看不到与 OkHttp(或我研究过的任何其他 Android HTTP 库)相同的模式。那么如何在 4 秒内执行 80 个 1-second-request 呢?它不是基于线程的,对吧?我没有启动 80(或 20)个线程?

具体来说,在com.squareup.okhttp.Call.beginRequest() ,我发现 sendRequestgetResponse 调用之间没有产生线程:

if (canceled) return null;

try {
engine.sendRequest();

if (request.body() != null) {
BufferedSink sink = engine.getBufferedRequestBody();
request.body().writeTo(sink);
}

engine.readResponse();
} catch (IOException e) {
HttpEngine retryEngine = engine.recover(e, null);
if (retryEngine != null) {
engine = retryEngine;
continue;
}

// Give up; recovery is not possible.
throw e;
}

Response response = engine.getResponse();

再一次,如何使 80 个“并行”调用成为可能?

为了使用该库,我不需要知道这一点,但我对异步编程很感兴趣,我真的很想了解 OkHttp/SquareInc 是如何解决这个问题的。

最佳答案

我自己做了一些测试,将 OkHttp 源链接到我的项目并将日志记录注入(inject)核心请求类 - Call.java。我发现 OkHttp 确实为每个调用使用了一个线程,并且在等待响应时确实 not yield,正如我错误地假设的那样。它比 Volley 更快的唯一原因是 Volley 硬编码了 4 个线程限制,而 OkHttp 使用 Integer.MAX_VALUE(Dipatcher.java 第 58 行):

executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));

这是我“异步”排队并执行 80 个请求时 LogCat 日志的摘录:

05-31 12:15:23.884  27989-28025/nilzor.okhttp I/OKH﹕ Starting request 1
05-31 12:15:23.884 27989-28026/nilzor.okhttp I/OKH﹕ Starting request 2
05-31 12:15:24.044 27989-28199/nilzor.okhttp I/OKH﹕ Starting request 79
05-31 12:15:24.054 27989-28202/nilzor.okhttp I/OKH﹕ Starting request 80
05-31 12:15:25.324 27989-28025/nilzor.okhttp I/OKH﹕ Getting response 1 after 1436ms
05-31 12:15:26.374 27989-28026/nilzor.okhttp I/OKH﹕ Getting response 2 after 2451ms
05-31 12:15:27.334 27989-28199/nilzor.okhttp I/OKH﹕ Getting response 79 after 3289ms
05-31 12:15:26.354 27989-28202/nilzor.okhttp I/OKH﹕ Getting response 80 after 2305ms

格式xxxxx-yyyyy的第三列表示进程id(x)和线程id(y)。注意每个请求如何获得自己的线程以及同一个线程如何处理响应。 Full log .这意味着我们在等待响应时有 80 个阻塞线程,这不是 true 异步编程应该完成的方式。

在 OkHttp/Square Inc 的辩护中,他们从未声称拥有真正的端到端异步 HTTP 通信,他们只为消费者提供异步接口(interface)。这很好。而且它的性能也很好,还能做很多其他的事情。这是一个很好的库,但我将其误解为具有真正的异步 HTTP 通信。

从那以后我就明白了要寻找关键字“NIO”来找到我要找的东西。像 AndroidAsync 这样的图书馆和 Ion看起来很有希望。

关于java - OkHttp 如何在不使用线程的情况下使用看似同步的 HTTP 连接执行并行 HTTP 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23955924/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com