我有一个异步函数,该函数调用其他异步函数。在Java中,如何等待异步调用完成(包括其中的所有嵌套异步调用)。
我已经可以被未来召唤,但是没有运气。
示例代码:
void asyncMehodA(){ }
void asyncMethodB() {
asyncMehodA();
}
我通过以下方式尝试了Future可调用项:
final Callable<Void> callable1 = new Callable<Void>() {
@Override
public Void call() {
asyncMethodB();
return null;
}
};
final Future<Void> callableFuture = mExecutor.submit(callable1);
try {
callableFuture.get();
} catch (final InterruptedException | ExecutionException e) {}
希望get函数将阻止执行,直到异步返回为止。但是,似乎get函数将触发异步调用并返回null。不等待asycn完成其执行。我在验证中添加了日志语句相同。如果我的理解是错误的,请纠正我。提出任何其他可以帮助我的概念。
答案 0 :(得分:1)
以下是使用CountDownLatch的示例。
package chapter13;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class BST {
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final ExecutorService executorService = Executors.newCachedThreadPool();
Runnable runnableA = () -> {
System.out.println("Runnable A");
latch.countDown();
System.out.println("Runnable A finished");
};
Runnable runnableB = () -> {
System.out.println("Runnable B");
executorService.submit(runnableA);
try {
System.out.println("Runnable B waiting for A to complete");
latch.await();
System.out.println("Runnable B finished");
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
Thread.currentThread().interrupt();
}
};
executorService.submit(runnableB);
Thread.sleep(10);
shutDown(executorService);
}
private static void shutDown(ExecutorService executorService) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(1, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}
}
}
我使用Thread.sleep()
方法使主线程休眠,因为在任务B提交后立即关闭池,这可能导致池在任务B提交任务A之前停止接受新任务。
答案 1 :(得分:0)
一种方法是使用Java锁定方法。 一个例子:
private AtomicBoolean processed = new AtomicBoolean(true) ;
private String result = null ;
public String doAndWait()
{
synchronized(processed) {
doSomethingAsync() ;
processed.wait();
}
return result ;
}
public void doSomethingAsync()
{
...
result="OK";
synchronized(processed) {
processed.notify();
}
}