1 回答
TA贡献1875条经验 获得超5个赞
不。这不是正确的方法。您提交一个进程,然后通过调用get()未来,您阻塞并等待它完成,因此它实际上是一个同步处理。有两种方法可以进行并行、异步处理:
1)invokeAll()
这是更简单的方法,但它需要您提前创建所有流程实例,因此这取决于您要执行多少并行任务(如果您有数百万个,您可能会达到内存限制)。创建流程后,您可以立即将它们提交给执行者。它将并行执行所有任务(根据线程池大小)并在所有任务完成后返回。
List<Callable<FileReadings>> tasks = new Arraylist<>();
for (File file : x.getFileList()) {
tasks.add(new Process(file));
}
// submit all processes at once. they will be processed in parallel
// this call blocks until all tasks are finished
List<Future<FileReadings>> responses = executor.invokeAll(tasks);
// at this point all processes finished. all get() will return immediately
for (Future<FileReadings> response : responses) {
x.totalCharacterCount += response.get().characterCount;
x.totalLineCount += response.get().lineCount;
}
2)submit()
当您创建一个进程并立即提交它时,此解决方案更具可扩展性,因此内存需求是恒定的(不包括执行程序)。但是,您需要自己管理响应:
List<Future<FileReadings>> responses = new ArrayList<>();
for (File file : x.getFileList()) {
responses.add(executor.submit(new Process(file)));
}
// at this point all processes submitted but not finished.
// need to check which is finished at intervarls
while (responses.isEmpty() == false) {
Thread.sleep(1000); // allow some processing time for tasks
// ListIterator allows removing items
ListIterator<Future<FileReadings>> itr = responses.listIterator();
while (itr.hasNext()) {
Future<FileReadings> response = itr.next();
// if task is complete, get it and remove from list
if (response.isDone()) {
x.totalCharacterCount += response.get().characterCount;
x.totalLineCount += response.get().lineCount;
itr.remove();
}
}
}
添加回答
举报
