简体   繁体   English

invokeAll 除了 CompletableFuture

[英]invokeAll but CompletableFuture

My task is to load file asynchronously using ExecutiveService & CompletableFuture, and to measure execution time for 2, 4, 8 threads and without parallelization我的任务是使用 ExecutiveService 和 CompletableFuture 异步加载文件,并测量 2、4、8 个线程且没有并行化的执行时间

It`s my first method:这是我的第一个方法:

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();

And it works finem but this way, i don`t use CompletableFuture, i have tried this:它工作得很好但是这样,我不使用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();

But i get almost the same time with different number of threads, although i have 31 file totaling 850mb, there should be a difference但是我得到的线程数几乎相同,虽然我有 31 个文件总计 850mb,但应该有所不同

How do i implement invokeAll but using CompletableFuture我如何实现 invokeAll 但使用 CompletableFuture

.join() waits for the result of each CompletableFuture before even submitting the next. .join()在提交下一个之前等待每个 CompletableFuture 的结果。 Here's an alternative:这是一个替代方案:

    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();
    }

Please be aware that allOf will return an exceptional result if just one of the tasks completes with an error.请注意,如果只有一个任务完成时出现错误, allOf将返回异常结果。 To handle errors, avoid throwing the RuntimeException within the task itself.要处理错误,请避免在任务本身内抛出 RuntimeException。 That way each file can be handled separately, and the process may be allowed to continue (or not, as you wish) even if an individual file has issues.这样每个文件都可以单独处理,即使单个文件有问题,也可以允许该过程继续(或不按您的意愿)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM