Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OkHttp如何在不使用线程的情况下,通过看似同步的HTTP连接执行并行HTTP请求?_Java_Multithreading_Asynchronous_Okhttp - Fatal编程技术网

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

Java OkHttp如何在不使用线程的情况下,通过看似同步的HTTP连接执行并行HTTP请求?,java,multithreading,asynchronous,okhttp,Java,Multithreading,Asynchronous,Okhttp,我已经用这个库做了一些性能测试,发现它很棒。在我的HTC One手机上,它在4.7秒内向我发送了80个请求,每次请求都会故意暂停1秒。我已经看过了代码,我试图找出它为什么这么快。开发人员(Square Inc.)宣传连接池和异步调用,我认为这两者都有助于提高性能 我来自.NET世界,在.NET4.5中,您有一个真正的异步HTTP库,其中包含一个异步。通过在等待响应时将线程交给操作系统,可以释放资源来启动更多HTTP请求或其他内容。问题是我看不到OkHttp(或我研究过的任何其他Android H

我已经用这个库做了一些性能测试,发现它很棒。在我的HTC One手机上,它在4.7秒内向我发送了80个请求,每次请求都会故意暂停1秒。我已经看过了代码,我试图找出它为什么这么快。开发人员(Square Inc.)宣传连接池和异步调用,我认为这两者都有助于提高性能

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

具体地说,在中,我看到
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();
那么,如何实现80个“并行”调用呢


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

OkHttp此时不使用异步套接字。如果将异步API与
enqueue()
一起使用,则
调度程序将启动多个线程并发出多个并发请求。如果您对所有请求使用相同的
OkHttp
客户端,那么它会将自身限制为每个主机5个连接。

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


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

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


从那时起,我就懂得了寻找关键字“NIO”来找到我正在寻找的东西。库似乎很有希望。

如果OkHttp将自身限制为每台主机5个连接,您如何解释我从一台主机收到了80条回复,而该主机总是在4.7秒内等待1秒才做出响应?@JesseWilson我想,只有在您不通过
setMaxRequestsPerHost()手动设置不同的值的情况下,每台主机5条请求才会起作用
?完全正确。你可以设置任何你想要的限制。5个连接实际上是指空闲连接。库本身不限制使用单个okhttpclient实例生成的连接数。您是一个接一个地发出请求,还是一次发出所有请求?如果它是一个接一个的,那么这必须花费>80的时间。如果所有这些同时发生,那么它可以任意快速下降到1。那么,您使用多少线程来发出调用呢?值得注意的是,您不应该将Volley与OkHttp进行比较。您应该在OkHttp之上使用截击。当您调用enqueue时,它会检查最大总请求数和每主机请求数。然后,它将请求添加到队列或直接执行它。另请参阅java的一个新的.net开发人员&如果我听到async立即假定IO完成端口(windows)和其他什么/POSIX AIO(linux)?我想知道okhttp3的文档“响应在请求线程上处理”(WTF?)是什么意思,以及它如何与RxJava调用适配器(需要RxScheduler)一起工作。终于找到了这条线路和boom..他们在rx中同步调用,使用调度程序代替okhttp3调度程序,这不是真正的异步编程应该如何完成的。
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
      new LinkedBlockingQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
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