简体   繁体   English

CompletableFuture 不等待子线程

[英]CompletableFuture is Not waiting for child threads

I am trying to wait for processor.processFiles() to complete, the method returns void and it is an @Async method.我正在尝试等待processor.processFiles()完成,该方法返回 void,它是一个 @Async 方法。 The busy wait logic does not cause the process to wait for method to complete.忙等待逻辑不会导致进程等待方法完成。 Can anybody please point out what am i missing?有人可以指出我错过了什么吗?

try{

    filesList.forEach(files -> {
        List<CompletableFuture<Void>> completableFutures  = new ArrayList<>();

        files.forEach(file-> {
            CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> 
                processor.processFiles());
            completableFutures.add(completableFuture);
        });
        while(true) {

            Thread.sleep(5000);
            boolean isComplete = completableFutures.stream().allMatch(result -> result.isDone() == true);

            if(isComplete){
                break;
            }
            LOGGER.info("processing the file...");
        }
    });
} 
catch(Exception e){

}
finally{
    closeConnections();
}

I think you've overcomplicated things.我认为你把事情复杂化了。

fileList.flatMap(List::stream).parallel().forEach(file -> processor.processFiles());

The forEach will run in parallel, and return when all of the files have been processed. forEach 将并行运行,并在处理完所有文件后返回。

At the very least, don't use side effects to populate a List .至少,不要使用副作用来填充List

List<CompletableFuture<Void>> completableFutures  = files.stream().map(
    file ->  CompletableFuture.runAsync(() -> processor.processFiles());
).collect( Collectors.toList());

I agree with the comment.我同意这个评论。

CompletableFuture<Void> all = CompletableFuture.allOf( completableFutures );

Then you can use get which will wait until the tasks are completed.然后你可以使用get ,它会等到任务完成。

Another way to do this, that would skip the List + CompletableFuture.allOf and just return a single completable future.另一种方法是跳过 List + CompletableFuture.allOf 并只返回一个可完成的未来。

CompletableFuture<Void> all = files.stream().map(
        file ->  CompletableFuture.runAsync(
            () -> processor.processFiles()
        )
    ).collect( 
        Collectors.reducing( 
           CompletableFuture.completedFuture(null), CompletableFuture::allOf
        )
    );

That will map file to a CompletableFuture then merge all of the resulting completable futures into a single completable future.这会将 map file写入 CompletableFuture,然后将所有生成的可完成未来合并为一个可完成未来。 You can call.get on it and it will return when everything is finished.你可以调用它,它会在一切完成后返回。

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

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