是否有可能执行比线程池中的线程更多的请求?
Is it possible to execute more requests than there are threads in thread pool?
我使用 Java 和 Spring 开发 Web 应用程序。为了检查系统在收到多个请求时的行为,我创建了测试:
@Test
public void shouldHandleMultipleRequests() throws Exception {
//given
final String endpoint = "http://localhost:9000/upload";
final File file = new File(format("src/test/resources/files/%s",
"file.txt"));
//when
final CompletableFuture<String> response1 = CompletableFuture.supplyAsync(() ->
Try.ofFailable(() ->
HttpClientBuilder.create().build().execute(
createHttpPost(endpoint, file))).orElse(null).getEntity().toString());
final CompletableFuture<String> response2 = CompletableFuture.supplyAsync(() ->
Try.ofFailable(() ->
HttpClientBuilder.create().build().execute(
createHttpPost(endpoint,file))).orElse(null).getEntity().toString());
assertThat(response1.get().contains("Something"));
assertThat(response2.get().contains("Something"));
}
一切正常,但我注意到,如果我尝试 运行 超过 3 个请求,则前 3 个请求和下一个请求之间会有延迟。
我的问题是
- 这种行为与我的处理器上的线程数有关(4 个线程处理器,3 个用于请求和等待响应的线程,一个用于应用程序),我说得对吗?
- 是否有办法同时发送 3 个以上的请求(当然是稍后检索响应)?
Java 线程是所谓的软线程,与处理器 cores/threads 号无关。
通常,HTTP 服务器和 Servlets/App 容器与线程池一起工作,这意味着一旦达到线程池上限,其余请求将保持阻塞状态。这就是阻塞的方法。
但是,还有另一种配置非阻塞连接器的选项。阅读这篇 Tomcat Connectors Document 可以获得更深入的知识。因此,如您所见,您可以调整服务器行为,因为这是连接器配置的问题。
当然,您可以同时生成三个以上的线程并收到 Future
个结果。
CompletableFuture.supplyAsync
uses common ForkJoinPool
to submit tasks which thread count by default is limited by number of hardware threads returned by Runtime.getRuntime().availableProcessors()
. You however can create your own pool and use it for your tasks using two-argument supplyAsync
:
ForkJoinPool myPool = new ForkJoinPool(100); // number of tasks executed in parallel
CompletableFuture.supplyAsync(..., myPool);
对于网络请求,线程数多于 CPU 个内核是很正常的。
我使用 Java 和 Spring 开发 Web 应用程序。为了检查系统在收到多个请求时的行为,我创建了测试:
@Test
public void shouldHandleMultipleRequests() throws Exception {
//given
final String endpoint = "http://localhost:9000/upload";
final File file = new File(format("src/test/resources/files/%s",
"file.txt"));
//when
final CompletableFuture<String> response1 = CompletableFuture.supplyAsync(() ->
Try.ofFailable(() ->
HttpClientBuilder.create().build().execute(
createHttpPost(endpoint, file))).orElse(null).getEntity().toString());
final CompletableFuture<String> response2 = CompletableFuture.supplyAsync(() ->
Try.ofFailable(() ->
HttpClientBuilder.create().build().execute(
createHttpPost(endpoint,file))).orElse(null).getEntity().toString());
assertThat(response1.get().contains("Something"));
assertThat(response2.get().contains("Something"));
}
一切正常,但我注意到,如果我尝试 运行 超过 3 个请求,则前 3 个请求和下一个请求之间会有延迟。
我的问题是
- 这种行为与我的处理器上的线程数有关(4 个线程处理器,3 个用于请求和等待响应的线程,一个用于应用程序),我说得对吗?
- 是否有办法同时发送 3 个以上的请求(当然是稍后检索响应)?
Java 线程是所谓的软线程,与处理器 cores/threads 号无关。
通常,HTTP 服务器和 Servlets/App 容器与线程池一起工作,这意味着一旦达到线程池上限,其余请求将保持阻塞状态。这就是阻塞的方法。
但是,还有另一种配置非阻塞连接器的选项。阅读这篇 Tomcat Connectors Document 可以获得更深入的知识。因此,如您所见,您可以调整服务器行为,因为这是连接器配置的问题。
当然,您可以同时生成三个以上的线程并收到 Future
个结果。
CompletableFuture.supplyAsync
uses common ForkJoinPool
to submit tasks which thread count by default is limited by number of hardware threads returned by Runtime.getRuntime().availableProcessors()
. You however can create your own pool and use it for your tasks using two-argument supplyAsync
:
ForkJoinPool myPool = new ForkJoinPool(100); // number of tasks executed in parallel
CompletableFuture.supplyAsync(..., myPool);
对于网络请求,线程数多于 CPU 个内核是很正常的。