如何等待主线程,直到异步方法完成?

时间:2020-04-03 20:45:07

标签: java spring spring-boot asynchronous java-8

我有使用start()方法的 Service.class

public void start()  {  
    for (int i = 0; i < companiesList.size(); i++) {
        asychronous.someAsynchronous(...);
    }
    log.info("Start method has finished");
}

我使用someAsynchronous()方法具有 Asynchronous.class

@Async("threadPoolTaskExecutor")
public CompletableFuture<Void> someAsynchronous(some_parameters) {
    //do some stuff
    return null;
}

log.info()方法完成之前出现someAsynchronous()。 如何强制它等待log.info()直到循环中的someSynchronous()方法完成?顺便说一句:异步线程仍在运行结束循环后。

1 个答案:

答案 0 :(得分:2)

要求执行CompletableFuture<Void>调用,但是在所有调用都在单独的线程中启动之后,for循环完成,并且甚至在其中任何一个完成之前就打印日志。这就是异步处理的优点-您不必关心它们的结果以及它们执行多少时间。

要实现所需的功能,必须定期检查所有所有是否已完成,然后再进行日志输出。

// Adds executions to the List
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < companiesList.size(); i++) {
    futures.add(asychronous.someAsynchronous(...));
}

// Periodical check
Iterator<CompletableFuture<Void>> iterator = futures.iterator();
while (iterator.hasNext()) {
    CompletableFuture<Void> future = iterator.next(); // get the next one
    if (future.isDone()) {                            // if finished...
        //...                                         // ... do an action
        iterator.remove();                            // ... and remove from the Iterator
    }
    if (!iterator.hasNext()) {                        // if you reach the end
        iterator = futures.iterator();                // ... repeat the remaining Futures
    }
}

log.info("Start method has finished");

请注意,只有完成所有执行后,该方法才会完成。


编辑:感谢 @Kayaman ,他建议使用一个专用的method来代替整个Iterator的逻辑。 futures必须是一个数组:

// Adds executions to the List
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < companiesList.size(); i++) {
    futures.add(asychronous.someAsynchronous(...));
}

// Join the completion of all the threads
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

log.info("Start method has finished");