【问题标题】:Java 8 parallelStream for concurrent Database / REST callJava 8 parallelStream 用于并发数据库/REST 调用
【发布时间】:2015-08-25 19:42:38
【问题描述】:

在这里,我使用 Javaparallel 流来遍历 List 并以每个列表元素作为输入调用 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);
}

【问题讨论】:

标签: java multithreading concurrency parallel-processing java-8


【解决方案1】:

您可以使用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;
}

【讨论】:

  • 我认为这一点的功能方面特别具有指导意义
  • 最后一行不应该是.collect(Collectors.toList());
【解决方案2】:

我不会回避同步访问您的ArrayList。鉴于您正在通过 Rest 访问远程服务,我怀疑同步的成本将是可以忽略的。我会在您花时间进行优化之前衡量效果。

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 2023-03-26
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 2014-05-27
    • 1970-01-01
    相关资源
    最近更新 更多