invokeAll в CompletableFuture
Моя задача загрузка файлов асинхронно используя ExecutiveService и CompletableFuture, при этом нужно будет измерить время выполнения при 2, 4, 8 потоках и без параллелизации
У меня есть такой метод:
File folderWithJson = new File(pathToFolderWithJson);
ExecutorService executorService = Executors.newFixedThreadPool(16);
Set<Callable<Boolean>> callables = new HashSet<>();
for(File file: Objects.requireNonNull(folderWithJson.listFiles())) {
callables.add(() -> {
System.out.println(Thread.currentThread().getName());
return getFineToStat(file);
});
}
executorService.invokeAll(callables);
executorService.shutdown();
И он отлично работает, но таким образом я не использую CompletableFuture , я опробовал такой метод:
File folderWithJson = new File(pathToFolderWithJson);
ExecutorService executorService = Executors.newFixedThreadPool(16);
for(File file: Objects.requireNonNull(folderWithJson.listFiles())) {
CompletableFuture.runAsync(() -> {
try {
getFineToStat(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
}, executorService).join();
}
executorService.shutdown();
Но у меня при разных количествах потоков получается почти одинаковое время, хотя у меня 31 файл суммой на 850мб, разница должна быть
Так к чему я веду, как мне реализовать invokeAll, но используя CompletableFuture?
Ответы (1 шт):
Я обычно использую комбинацию методов allOf() и join()/get(). Первый формирует композитный CompletableFuture из массива, любой из вторых ожидает завершения задач(и)
ExecutorService executorService = Executors.newFixedThreadPool(16);
List<CompletableFuture<Void>> tasks = new ArrayList<>();
for(File file: Objects.requireNonNull(folderWithJson.listFiles())) {
CompletableFuture<Void> task = CompletableFuture.runAsync(() -> {
try {
getFineToStat(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
}, executorService);
tasks.add(task);
}
CompletableFuture<Void> allFutures = CompletableFuture.allOf(tasks.toArray(new CompletableFuture[0]));
allFutures.join();
executorService.shutdown();