[Java]等待Java异步调用完成

时间:2019-03-31 20:42:02

标签: java synchronization

我有一个异步函数,该函数调用其他异步函数。在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完成其执行。我在验证中添加了日志语句相同。如果我的理解是错误的,请纠正我。提出任何其他可以帮助我的概念。

2 个答案:

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