Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.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中执行非阻塞HTTP调用?_Java_Completable Future - Fatal编程技术网

如何在Java中执行非阻塞HTTP调用?

如何在Java中执行非阻塞HTTP调用?,java,completable-future,Java,Completable Future,我有一个第三方API,我使用HTTPGET请求调用它。每个请求都需要几秒钟才能得到响应 目前,我正在使用CompletableFuture,它是在大小为64的FixedThreadPool上执行的。这会导致线程被阻塞,直到它收到GET请求的响应,即线程在发送GET响应后处于空闲状态,直到它们收到响应。因此,我可以发送的最大并发请求数受到线程大小的限制,即此处为64 我可以用什么来代替CompletableFuture,这样我的线程就不会闲置等待响应了?正如@user207421所说: 真正的异

我有一个第三方API,我使用HTTPGET请求调用它。每个请求都需要几秒钟才能得到响应

目前,我正在使用CompletableFuture,它是在大小为64的FixedThreadPool上执行的。这会导致线程被阻塞,直到它收到GET请求的响应,即线程在发送GET响应后处于空闲状态,直到它们收到响应。因此,我可以发送的最大并发请求数受到线程大小的限制,即此处为64

我可以用什么来代替CompletableFuture,这样我的线程就不会闲置等待响应了?

正如@user207421所说:

  • 真正的异步(即事件驱动)HTTP客户端应用程序是复杂的
  • 多线程(但基本上是同步的)HTTP客户机应用程序更简单,可以扩展到内存所能容纳的线程数
  • 假设您有64个工作线程处理请求,实际的瓶颈可能是物理网络带宽或可用的客户端CPU。如果您已达到这些限制,则:

    • 增加辅助线程的数量不会有帮助,而且
    • 切换到异步(事件驱动)模型不会有帮助
  • 第三种可能是瓶颈是服务器端资源限制或速率限制。在这种情况下,增加客户端线程数可能会有所帮助,但没有效果,或者使问题变得更糟。这将取决于服务器的实现方式、请求的性质等

如果瓶颈实际上是线程的数量,那么一个简单的尝试就是减小辅助线程堆栈的大小,以便可以运行更多线程。默认堆栈大小通常为1MB,这可能会比需要的大很多。(这还将减少空闲线程的…呃…内存开销,如果这是一个真正的问题的话。)

有一些Java异步HTTP客户端库。但我从未使用过,也不能推荐。就像@user207421一样,我不相信改变的努力会有回报


我该怎么做才能使我的线程不闲置等待响应

空闲线程实际上不是问题所在。空闲线程只使用内存(以及一些可能的次要影响,这些影响在这里可能并不重要)。除非你记性不好,否则不会有什么不同

注意:当线程等待服务器响应时,如果客户端需要执行其他操作,OS线程调度程序将切换到其他线程

因此,我可以发送的最大并发请求数受到线程[池]大小的限制,即此处为64

这是真的。然而,同时发送更多的请求可能不会有帮助。如果客户端线程处于空闲状态,这可能意味着瓶颈要么是网络,要么是服务器端。如果是这种情况,添加更多线程不会增加吞吐量。相反,单个请求将花费(平均)更长的时间,吞吐量将保持不变。。。或者,如果服务器开始从其请求队列中删除请求,则可能会删除


最后,如果您担心大量闲置的工作线程池(等待下一个任务执行)的开销,请使用执行服务或连接池,该服务或连接池可以收缩和增长其线程池以满足不断变化的工作负载。

因此,增加线程池,或使用无限制的线程池。但是您真的同时有64个挂起的GET请求吗?实际上,我可以同时有数千个GET请求。有没有其他方法可以代替使用如此大的线程池?线程只需发送GET请求并收集响应。几千个空闲线程没有问题,非阻塞HTTP很难实现。拥有多个线程的问题是,我们可能需要在扩展时保持线程池的大小不断变化。而且我们可以在Java虚拟机上使用的线程大小也没有那么大(根据这个答案是6500)。所以把它调低。无论如何,实际上无法同时执行数千个GET请求。网络不是多线程的。但是你提到的问题已经八年了。你需要做一些实验。