java 调用除CompletableFuture之外的所有内容

dbf7pr2w  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(133)

我的任务是使用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

8nuwlpux

8nuwlpux1#

.join()等待每个CompletableFuture的结果,然后才提交下一个。

final ExecutorService executorService = Executors.newFixedThreadPool(16);
    //try with resources and using a Stream over the files (`Path`s) in the directory:
    try(Stream<Path> paths = Files.list(folderWithJson.toPath())) {
        final CompletableFuture<?>[] all = paths
               //each Path is mapped to a CompletableFuture, to be run on the ExecutorService:
               .map(path -> CompletableFuture.runAsync(() -> {
                   try {
                       getFineToStat(path.toFile());
                   } catch (IOException e) {
                       throw new RuntimeException(e);
                   }
               }, executorService))
               //we collect them into a new array, so that we can use them later
               .toArray(CompletableFuture[]::new);
        //this will wait for all to finish:
        CompletableFuture.allOf(all).join();
        executorService.shutdown();
    }

请注意,如果只有一个任务完成时出错,则整个进程可能会中止。要处理错误,请避免在任务本身中引发RuntimeException。这样,每个文件都可以单独处理,即使单个文件有问题,也可以允许进程继续(或不继续,根据您的意愿)。

相关问题