1 回答

TA貢獻1875條經驗 獲得超5個贊
不。這不是正確的方法。您提交一個進程,然后通過調用get()未來,您阻塞并等待它完成,因此它實際上是一個同步處理。有兩種方法可以進行并行、異步處理:
1)invokeAll()
這是更簡單的方法,但它需要您提前創建所有流程實例,因此這取決于您要執行多少并行任務(如果您有數百萬個,您可能會達到內存限制)。創建流程后,您可以立即將它們提交給執行者。它將并行執行所有任務(根據線程池大?。┎⒃谒腥蝿胀瓿珊蠓祷亍?/p>
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();
}
}
}
添加回答
舉報