Nil*_*zor 16 java multithreading asynchronous okhttp
我已经使用OkHttp库进行了一些性能测试,发现它很棒.它向http://httpbin.org/delay/1提出了80个请求,它在我的HTC One手机上的4.7秒内故意暂停每个请求1秒.我查看了代码,我试图找出它为什么这么快.开发人员(Square Inc)宣传连接池和异步调用,我认为这两者都有助于提高性能.
我来自.NET世界,在.NET 4.5中,您有一个真正的异步HTTP库和Async GetResponse方法.通过在等待响应时将线程交给操作系统,您可以释放资源以启动更多HTTP请求或其他内容.问题是我看不到与OkHttp相同的模式(或者我已经研究过的任何其他Android库).那么我怎么能在4秒内执行80个1秒的请求呢?它不是基于线程的,对吧?我没有开出80(或20)个线程?
具体来说,在com.squareup.okhttp.Call.beginRequest()中,我看到并没有让sendRequest和getResponse调用之间产生线程:
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();
Run Code Online (Sandbox Code Playgroud)
那么,如何才能实现80个"并行"呼叫?
我不需要知道这个以便使用库,但异步编程让我感兴趣,我真的很想了解OkHttp/SquareInc是如何解决这个问题的.
Nil*_*zor 19
我通过将OkHttp源链接到我的项目并将日志记录注入核心请求类 - Call.java来自行测试.我发现OkHttp确实为每个调用使用了一个线程,并且在我错误地假设时等待响应时不会产生.它比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));
Run Code Online (Sandbox Code Playgroud)
当我排队并"异步"处理80个请求时,这是LogCat日志的一个exerpt:
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
Run Code Online (Sandbox Code Playgroud)
格式的第三列xxxxx-yyyyy表示进程id(x)和线程id(y).注意每个请求如何获得自己的线程以及相同的线程如何处理响应.完整日志.这意味着我们有80个阻塞线程在等待回应,这是不如何真正的异步编程应该做的.
在OkHttp/Square Inc的辩护中,他们从未声称拥有真正的端到端异步HTTP通信,他们只向消费者提供异步接口.哪个好.它也表现良好,并做了很多其他的东西.它是一个很好的库,但我错误地解释了它是否具有真正的异步HTTP通信.
我已经理解为寻找关键词"NIO"来找到我正在寻找的东西.像AndroidAsync和Ion这样的图书馆看起来很有希望.
Jes*_*son 13
OkHttp目前不使用异步套接字.如果您正在使用异步API enqueue(),Dispatcher则会启动多个线程并发出多个并发请求.如果OkHttp对所有请求使用相同的客户端,则每个主机将自己限制为5个连接.