我使用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个请求和下一个请求之间会有延迟。
我的问题是
答案 0 :(得分:1)
Java线程称为软线程,与处理器核心/线程数无关。
通常,HTTP服务器和Servlet / App容器与线程池一起工作,这意味着一旦达到线程池上限,其余的请求仍然被阻止。这就是阻止方法。
但是,还有另一个选项可以配置非阻塞连接器。阅读Tomcat Connectors Document可以获得更深入的知识。因此,正如您所看到的,您可以调整服务器行为,因为它是连接器配置的问题。
当然,您可以同时生成三个以上的线程并获得Future
个结果。
答案 1 :(得分:1)
CompletableFuture.supplyAsync
使用公共ForkJoinPool
提交任务,默认情况下线程数受Runtime.getRuntime().availableProcessors()
返回的硬件线程数限制。但是,您可以使用双参数supplyAsync
创建自己的池并将其用于任务:
ForkJoinPool myPool = new ForkJoinPool(100); // number of tasks executed in parallel
CompletableFuture.supplyAsync(..., myPool);
对于网络请求,拥有比CPU内核更多的线程是很正常的。