【问题标题】:Can we improve performance on lists other than java 8 parallel streams我们可以提高除 java 8 并行流以外的列表的性能吗
【发布时间】:2019-03-23 08:57:42
【问题描述】:

我必须通过调用返回 List 的 rest API 从某处转储数据。

  1. 首先我必须从一个 rest api 中获取一些 List 对象。现在使用并行流并使用 forEach 遍历每个项目。

  2. 现在,对于每个元素,我必须调用其他一些 api 来获取再次返回列表的数据,并通过调用另一个 rest api 保存相同的列表。

  3. 步骤 1 的 6000 条记录大约需要 1 小时。

我尝试如下:

restApiMethodWhichReturns6000Records
    .parallelStream().forEach(id ->{
       anotherMethodWhichgetsSomeDataAndPostsToOtherRestCall(id);
                       });


public void anotherMethodWhichgetsSomeDataAndPostsToOtherRestCall(String id) {

     sestApiToPostData(url,methodThatGetsListOfData(id));
}

【问题讨论】:

  • 这与列表的性能无关。它与 REST 服务或您的网络或两者的速度有关。
  • 看起来你按顺序调用了其他的rest api,而不是同时调用。
  • @AlexeiKaigorodov 你能改进上面的代码块吗?我在上面使用了并行流。我哪里写错了?
  • @Pavan 请提供方法 sestApiToPostData 和 methodThatGetsListOfData 的代码。它们必须是非阻塞的。

标签: java multithreading parallel-processing stream java-stream


【解决方案1】:

parallelStream 有时会导致意外行为。它使用常见的ForkJoinPool。因此,如果您在代码的其他地方有并行流,它可能对长时间运行的任务具有阻塞性质。即使在同一个流中,如果某些任务很耗时,所有工作线程也会被阻塞。

对此stackoverflow 进行了很好的讨论。在这里,您会看到一些分配特定任务 ForkJoinPool 的技巧。

首先确保您的 REST 服务是非阻塞的。

您可以做的另一件事是通过向 JVM 提供 -Djava.util.concurrent.ForkJoinPool.common.parallelism=4 来调整池大小。

【讨论】:

    【解决方案2】:

    如果 API 调用被阻塞,即使您并行运行它们,您也只能并行执行几个调用。

    我会尝试使用CompletableFuture 的解决方案。

    代码是这样的:

    List<CompletableFuture>> apiCallsFutures = restApiMethodWhichReturns6000Records
        .stream()
        .map(id -> CompletableFuture.supplyAsync(() -> getListOfData(id))    // Mapping the get list of data call to a Completable Future
                                     .thenApply(listOfData -> callAPItoPOSTData(url, listOfData))   // when the get list call is complete, the post call can be performed 
        .collect(Collectors.toList());
    
    CompletableFuture[] completableFutures = apiCallsFutures.toArray(new CompletableFuture[apiCallsFutures.size()]); // CompletableFuture.allOf accepts only arrays :(
    
    CompletableFuture<Void> all = CompletableFuture.allOf(completableFutures); // Combine all the futures
    
    all.get(); // perform calls
    

    有关 CompletableFutures 的更多详细信息,请查看:https://www.baeldung.com/java-completablefuture

    【讨论】:

      猜你喜欢
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多