Async await in Java

Writing asynchronous code is hard. Trying to understand what asynchronous code is supposed to be doing is even harder. Promises are a common way to attempt to describe the flow of delayed-execution: first do a thing, then do another thing, in case of error do something else.

In many languages promises have become the de facto way to orchestrate asynchronous behaviour. Java 8 finally got with the program and introduced CompletableFuture; although seriously, who designed the API? It’s a mess!

The trouble with promises is that the control flow can become anything but simple. As the control flow becomes more complex it becomes virtually impossible to understand (do this, then that, unless it’s Wednesday, in which case do this other thing, if there’s an error go back three spaces, yada yada yada).

The cool kids have moved on to using async…await. C# has it. JavaScript has it. And now… and now, via some of the big brains at EA, Java has it! Yes, Java has a usable async…await construct, without changing the language!

A simple example: we could compose a couple of asynchronous operations using CompletableFuture as follows:

It looks like synchronous code. But the calls to Async.await are magic. These calls are re-written (at runtime or build time, as you prefer) to make the calls non-blocking!

The code is much easier to write, much easier to read, a million times easier to debug and most importantly it scales naturally. As code becomes more complex you can use normal refactoring tools to keep it under control. With CompletableFutures you end up passing around all these future objects and, somewhere along the line, one day you’re going to miss a code path and boom! One free bug in production.

So even if you’re stuck using Java, you can still be like the cool kids and use async…await!

Post navigation

2 thoughts on “Async await in Java”

It’s about to be released shortly (need to add some documentation, the code itself is complete). Comparing to the EA implementation it has several benefits:

1. EA implementation neither let you specify where your code will be resumed once await-ed nor it provides a way to capture execution context before suspend and restore it after resume. Trust me, it’s an ultimate requirement in managed environment like JEE or JavaFX. My library has the Scheduler (direct analogy is SynchronizationContext in .NET) and SchedulerResolver – that lets you get an effective Scheduler implicitly or explicitly.

2. In EA implementation there is no way to cancel async method from the outside. In .NET there is the CancellationToken that provides necessary functionality, though, a bit inconvenient to use. In my Tascalate Async/Await it’s possible to use Future.cancel() to truly interrupt execution of async method (typically, blocking and/or IO-Bound). At least, it’s guaranteed to interrupt async method once it’s entered “awaiting” state. For CPU-bound computational async methods there is an option to check for interruption flag and exit early cooperatively.