用于并发数据库/REST调用的Java 8 parallelStream
在这里,我使用Javaparallel stream对列表进行迭代,并使用每个列表元素作为输入调用REST调用。我需要将REST调用的所有结果添加到使用用于并发数据库/REST调用的Java 8 parallelStream,java,multithreading,concurrency,parallel-processing,java-8,Java,Multithreading,Concurrency,Parallel Processing,Java 8,在这里,我使用Javaparallel stream对列表进行迭代,并使用每个列表元素作为输入调用REST调用。我需要将REST调用的所有结果添加到使用ArrayList的集合中。下面给出的代码运行良好,只是ArrayList的非线程安全性会导致不正确的结果,并且添加所需的同步会导致争用,破坏并行性的好处 有人能给我建议一种在我的案例中使用并行流的正确方法吗 public void myMethod() { List<List<String>> partition
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);
}
public void myMethod(){
List partitions=getInputData();
最终列表allResult=new ArrayList();
partitions.parallelStream().forEach(serverList->callRestAPI(serverList,allResult);
}
私有void callRestAPI(列表服务器列表,列表所有结果){
List result=//执行REST调用。
allResult.addAll(结果);
}
我不会回避同步访问您的阵列列表
。考虑到您通过Rest访问远程服务,我怀疑同步的成本可以忽略不计。我会在您花时间优化之前衡量效果。您可以使用map
而不是forEach
执行操作-这将保证线程安全(并且从函数编程的角度来看更干净):
我认为,特别是在功能方面,这是一个说明。最后一行不应该是
.collect(Collectors.toList());
这个问题已经得到了回答,但是我建议您不要使用并行流并行执行多个API调用。有关解释,请参阅此问题和答案:
List<String> allResult = partitions.parallelStream()
.map(this::callRestAPI)
.flatMap(List::stream) //flattens the lists
.collect(toList());
private List<String> callRestAPI(List<String> serverList) {
List<String> result = //Do a REST call.
return result;
}