Java 并行化for循环并填充多个数据结构

Java 并行化for循环并填充多个数据结构,java,multithreading,thread-safety,executorservice,Java,Multithreading,Thread Safety,Executorservice,我有一个我想并行化的for循环。在下面的代码中,我迭代了最外层的for循环,并将条目放入各种数据结构中,它工作得很好。所有这些数据结构在同一个类中都有一个getter,我稍后将使用它从其他类中获取for循环中的所有细节。我正在填充info、itemToNumberMapping、catToValueHolder、tasksByCategory、catHolder、itemIds数据结构,它们也有getter // want to parallelize this for loop for

我有一个我想并行化的for循环。在下面的代码中,我迭代了最外层的for循环,并将条目放入各种数据结构中,它工作得很好。所有这些数据结构在同一个类中都有一个getter,我稍后将使用它从其他类中获取for循环中的所有细节。我正在填充info、itemToNumberMapping、catToValueHolder、tasksByCategory、catHolder、itemIds数据结构,它们也有getter

  // want to parallelize this for loop
  for (Task task : tasks) {
    if (task.getCategories().isEmpty() || task.getEventList() == null
        || task.getMetaInfo() == null) {
      continue;
    }
    String itemId = task.getEventList().getId();
    String categoryId = task.getCategories().get(0).getId();
    Processor fp = new Processor(siteId, itemId, categoryId, poolType);
    Map<String, Integer> holder = fp.getDataHolder();
    if (!holder.isEmpty()) {
      for (Map.Entry<String, Integer> entry : holder.entrySet()) {
        info.putIfAbsent(entry.getKey(), entry.getValue());
      }
      List<Integer> values = new ArrayList<>();
      for (String key : holder.keySet()) {
        values.add(info.get(key));
      }
      itemToNumberMapping.put(itemId, StringUtils.join(values, ","));
      catToValueHolder.put(categoryId, StringUtils.join(values, ","));
    }
    Category cat = getCategory(task, holder.isEmpty());
    tasksByCategory.add(cat);
    LinkedList<String> ids = getCategoryIds(task);
    catHolder.put(categoryId, ids.getLast());
    itemIds.add(itemId);
  }
更新:-

我正在并行化do-while循环中的for循环,并且我的do-while循环一直运行到页面数小于或等于页面数为止。所以也许我做得不对。因为我的do-while循环将一直运行到所有页面都完成为止,对于每个页面,我都有一个for循环,我正在尝试并行化它,并且按照我设置它的方式,它给出了rejectedexecutionexception


您不必从并行代码中输出某些内容。您只需获取外部循环的主体,并为每个项目创建一个任务,如下所示:

for (Task task : tasks) {
   Callable<Void> c = new Callable<>() {
      public void call() {
         if (task.getCategories().isEmpty() || task.getEventList() == null || task.getMetaInfo() == null) {
               // ... rest of code here
          }
       }
    };
    executorService.submit(c);
 }

// wait for executor service, check for exceptions or whatever else you want to do here

好的,有道理。。只是为了确保您的if检查是针对isNotEmpty和isNotNull的,对吗?如果我能把所有东西都放进去的话?我已经用新代码更新了我的问题,所以你能告诉我这看起来是否正确吗?我在按照你建议的方式运行时遇到了RejectedExecutionException异常。我再次更新了我的问题,并提供了我正在做的一些细节。你能看一下,让我知道我是否需要做任何更改吗?在你完成提交所有任务之前是否会调用关机?如果shutdown错误地位于for循环中,那么就会发生这种情况。我不这么认为它被调用了。我已经更新了问题的更多细节。你能检查一下我是对的还是出了什么问题吗?
  private void check() {
    String endpoint = "some_url";
    int number = 1;
    int pages = 0;
    do {
      ExecutorService executorService = Executors.newFixedThreadPool(10);
      for (int i = 1; i <= retryCount; i++) {
        try {
          HttpEntity<String> requestEntity =
              new HttpEntity<String>(getBody(number), getHeader());
          ResponseEntity<String> responseEntity =
              HttpClient.getInstance().getClient()
                  .exchange(URI.create(endpoint), HttpMethod.POST, requestEntity, String.class);
          String jsonInput = responseEntity.getBody();
          Process response = objectMapper.readValue(jsonInput, Process.class);
          pages = (int) response.getPaginationResponse().getTotalPages();
          List<Task> tasks = response.getTasks();
          if (pages <= 0 || tasks.isEmpty()) {
            continue;
          }
          // want to parallelize this for loop
          for (Task task : tasks) {
            Callable<Void> c = new Callable<>() {
              public void call() {
                if (!task.getCategories().isEmpty() && task.getEventList() != null
                    && task.getMetaInfo() != null) {
                    // my code here
                }
              }
            };
            executorService.submit(c);
          }
          // is this at right place? because I am getting rejectedexecutionexception
          executorService.shutdown();
          number++;
          break;
        } catch (Exception ex) {
          // log exception
        }
      }
    } while (number <= pages);
  }
for (Task task : tasks) {
   Callable<Void> c = new Callable<>() {
      public void call() {
         if (task.getCategories().isEmpty() || task.getEventList() == null || task.getMetaInfo() == null) {
               // ... rest of code here
          }
       }
    };
    executorService.submit(c);
 }

// wait for executor service, check for exceptions or whatever else you want to do here