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