Java Equivalent of C# async/await?

No, there isn't any equivalent of async/await in Java - or even in C# before v5.

It's a fairly complex language feature to build a state machine behind the scenes.

There's relatively little language support for asynchrony/concurrency in Java, but the java.util.concurrent package contains a lot of useful classes around this. (Not quite equivalent to the Task Parallel Library, but the closest approximation to it.)


The await uses a continuation to execute additional code when the asynchronous operation completes (client.GetStringAsync(...)).

So, as the most close approximation I would use a CompletableFuture<T> (the Java 8 equivalent to .net Task<TResult>) based solution to process the Http request asynchronously.

UPDATED on 25-05-2016 to AsyncHttpClient v.2 released on Abril 13th of 2016:

So the Java 8 equivalent to the OP example of AccessTheWebAsync() is the following:

CompletableFuture<Integer> AccessTheWebAsync()
{
    AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
    return asyncHttpClient
       .prepareGet("http://msdn.microsoft.com")
       .execute()
       .toCompletableFuture()
       .thenApply(Response::getResponseBody)
       .thenApply(String::length);
}

This usage was taken from the answer to How do I get a CompletableFuture from an Async Http Client request? and which is according to the new API provided in version 2 of AsyncHttpClient released on Abril 13th of 2016, that has already intrinsic support for CompletableFuture<T>.

Original answer using version 1 of AsyncHttpClient:

To that end we have two possible approaches:

  • the first one uses non-blocking IO and I call it AccessTheWebAsyncNio. Yet, because the AsyncCompletionHandler is an abstract class (instead of a functional interface) we cannot pass a lambda as argument. So it incurs in inevitable verbosity due to the syntax of anonymous classes. However, this solution is the most close to the execution flow of the given C# example.

  • the second one is slightly less verbose however it will submit a new Task that ultimately will block a thread on f.get() until the response is complete.

First approach, more verbose but non-blocking:

static CompletableFuture<Integer> AccessTheWebAsyncNio(){
    final AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
    final CompletableFuture<Integer> promise = new CompletableFuture<>();
    asyncHttpClient
        .prepareGet("https://msdn.microsoft.com")
        .execute(new AsyncCompletionHandler<Response>(){
            @Override
            public Response onCompleted(Response resp) throws Exception {
                promise.complete(resp.getResponseBody().length());
                return resp;
            }
        });
    return promise;
}

Second approach less verbose but blocking a thread:

static CompletableFuture<Integer> AccessTheWebAsync(){
    try(AsyncHttpClient asyncHttpClient = new AsyncHttpClient()){
        Future<Response> f = asyncHttpClient
            .prepareGet("https://msdn.microsoft.com")
            .execute();
        return CompletableFuture.supplyAsync(
            () -> return f.join().getResponseBody().length());
    }
}

Check out ea-async which does Java bytecode rewriting to simulate async/await pretty nicely. Per their readme: "It is heavily inspired by Async-Await on the .NET CLR"

Tags:

C#

Java