我的任务是使用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个文件总计850mb,应该有区别
如何在不使用CompletableFuture的情况下实现invokeAll
1条答案
按热度按时间8nuwlpux1#
.join()
等待每个CompletableFuture的结果,然后才提交下一个。请注意,如果只有一个任务完成时出错,则整个进程可能会中止。要处理错误,请避免在任务本身中引发RuntimeException。这样,每个文件都可以单独处理,即使单个文件有问题,也可以允许进程继续(或不继续,根据您的意愿)。