Java 8 parallelStream 用于并发数据库/REST 调用
Java 8 parallelStream for concurrent Database / REST call
在这里,我使用 Javaparallel 流遍历列表并调用 REST 调用,每个列表元素作为输入。我需要将 REST 调用的所有结果添加到我正在使用 ArrayList
的集合中。下面给出的代码工作正常,除了 ArrayList 的非线程安全会导致不正确的结果,并且添加所需的同步会导致争用,破坏并行的好处。
有人可以建议我使用并行流的正确方法吗?
public void myMethod() {
List<List<String>> partitions = getInputData();
final List<String> allResult = new ArrayList<String>();
partitions.parallelStream().forEach(serverList -> callRestAPI(serverList, allResult);
}
private void callRestAPI(List<String> serverList, List<String> allResult) {
List<String> result = //Do a REST call.
allResult.addAll(result);
}
我不会回避同步访问您的 ArrayList
。鉴于您正在通过 Rest 访问远程服务,我怀疑同步成本将 可以忽略不计 。在你花时间优化之前,我会衡量效果。
您可以使用 map
而不是 forEach
执行操作 - 这将保证线程安全(并且从函数式编程的角度来看更清晰):
List<String> allResult = partitions.parallelStream()
.map(this::callRestAPI)
.flatMap(List::stream) //flattens the lists
.collect(toList());
还有你的callRestAPI
方法:
private List<String> callRestAPI(List<String> serverList) {
List<String> result = //Do a REST call.
return result;
}
在这里,我使用 Javaparallel 流遍历列表并调用 REST 调用,每个列表元素作为输入。我需要将 REST 调用的所有结果添加到我正在使用 ArrayList
的集合中。下面给出的代码工作正常,除了 ArrayList 的非线程安全会导致不正确的结果,并且添加所需的同步会导致争用,破坏并行的好处。
有人可以建议我使用并行流的正确方法吗?
public void myMethod() {
List<List<String>> partitions = getInputData();
final List<String> allResult = new ArrayList<String>();
partitions.parallelStream().forEach(serverList -> callRestAPI(serverList, allResult);
}
private void callRestAPI(List<String> serverList, List<String> allResult) {
List<String> result = //Do a REST call.
allResult.addAll(result);
}
我不会回避同步访问您的 ArrayList
。鉴于您正在通过 Rest 访问远程服务,我怀疑同步成本将 可以忽略不计 。在你花时间优化之前,我会衡量效果。
您可以使用 map
而不是 forEach
执行操作 - 这将保证线程安全(并且从函数式编程的角度来看更清晰):
List<String> allResult = partitions.parallelStream()
.map(this::callRestAPI)
.flatMap(List::stream) //flattens the lists
.collect(toList());
还有你的callRestAPI
方法:
private List<String> callRestAPI(List<String> serverList) {
List<String> result = //Do a REST call.
return result;
}