Wait for Java Async Call to Complete

Wait for Java Async Call to Complete

I have a async function that calls other async function. In Java, how to wait on untill the async call completes(including any nested async calls in it).

I already Future callable But no luck.

Sample code:

void asyncMehodA(){ }

void asyncMethodB() {
asyncMehodA();
}

I tried the Future callable in the following way:

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) {}

hoping that the get function will block the execusion untill the async return. But seems the get function will fire the async call and reurn null. not waiting for the asycn to complete its execusion. I added log statements in the verified the same. Please correct me if my understanding is wrong. suggest any other concepts that can aid me.

2 Answers

Here is an example using 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();
        }

    }


}

I use Thread.sleep() method to sleep the main thread, because shuting down the pool immediately after task B was submitted, might cause the pool to stop accepting new tasks before task A is submitted by task B.

One way would be to use a java locking method. An example:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling
Author

James H. Sterling

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.