我编写了几行代码,将向我机器上运行的服务发送 50 个 HTTP GET 请求。该服务将始终sleep 1第二个并返回一个带有空正文的 HTTP 状态代码 200。正如预期的那样,代码运行了大约 50 秒。
为了加快速度,我尝试创建一个ExecutorService有 4 个线程的线程,这样我就可以始终同时向我的服务发送 4 个请求。我预计代码运行大约 13 秒。
final List<String> urls = new ArrayList<>();
for (int i = 0; i < 50; i++)
urls.add("http://localhost:5000/test/" + i);
final RestTemplate restTemplate = new RestTemplate();
final List<Callable<String>> tasks = urls
.stream()
.map(u -> (Callable<String>) () -> {
System.out.println(LocalDateTime.now() + " - " + Thread.currentThread().getName() + ": " + u);
return restTemplate.getForObject(u, String.class);
}).collect(Collectors.toList());
final ExecutorService executorService = Executors.newFixedThreadPool(4);
final long start = System.currentTimeMillis();
try {
final List<Future<String>> futures = executorService.invokeAll(tasks);
final List<String> results = futures.stream().map(f -> {
try {
return f.get();
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException(e);
}
}).collect(Collectors.toList());
System.out.println(results);
} finally {
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
}
final long elapsed = System.currentTimeMillis() - start;
System.out.println("Took " + elapsed + " ms...");
因此,出于调试目的,我将 HTTP 请求更改为sleep调用:
// return restTemplate.getForObject(u, String.class);
TimeUnit.SECONDS.sleep(1);
return "";
现在代码按预期工作:
...
Took 13068 ms...
所以我的问题是为什么带有 sleep 调用的代码按预期工作,而带有 HTTP 请求的代码却没有?我怎样才能让它按照我预期的方式行事?
临摹微笑
相关分类