【发布时间】:2017-11-29 22:19:00
【问题描述】:
一点背景知识,我尝试使用 Java 8 并行流以异步方式调用多个 API。我希望调用每个 API,然后阻塞,直到返回所有 API。我遇到了一个有趣的情况,如果我尝试流式传输地图而不是列表,API 将不再在新线程中被调用。
如果我运行以下代码,每个服务都会在一个新线程中调用:
List<GitUser> result1 = Arrays.asList(service1, service2, service3).parallelStream()
.map(s->s.getGitUser())
.collect(Collectors.toList());
但是,如果我使用地图来完成相同的任务,则每个服务都会被同步调用:
Map<String, ParallelStreamPOCService> map = new HashMap<>();
map.put("1", service1);
map.put("2", service2);
map.put("3", service3);
List<GitUser> result2 = map.entrySet().parallelStream()
.map(s->s.getValue().getGitUser())
.collect(Collectors.toList());
这里是服务实现:
public GitUser getGitUser() {
LOGGER.info("Loading user " + userName);
String url = String.format("https://api.github.com/users/%s", userName);
GitUser results = restTemplate.getForObject(url, GitUser.class);
try {
TimeUnit.SECONDS.sleep(secondsToSleep);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
LOGGER.error("Finished " + userName);
return results;
}
【问题讨论】:
-
您的样本太小,无法得出任何明确的结论。尝试一千个元素,看看你是否观察到相同的东西。
-
我试图通过告诉线程休眠 x 秒来在较小的集合中模拟这一点。如果我 service1 休眠 10 秒,service2 休眠 1 秒,我希望 service2 先返回。
-
注意:你的意思是“方式”,而不是“庄园”。前者的意思是“方式”;后者的意思是“有土地的大乡间别墅”。
-
I would expect service2 to return first,你可能就在这里,但这意味着公平——并行流不能保证
标签: java multithreading concurrency java-stream