(Originally Published 20-Dec-2016) Java 9 concurrency updates: CompletableFuture and java.util.concurrent.Flow
Java 9 was released in September 2017, and it came with a list of new and revised features, methods, and other elements. In our search through the JDK enhancement proposals (JEP), we came across JEP 266. It holds some interesting updates to CompletableFuture, Concurrency updates and support for Reactive Streams, that caught our attention.
In the following post we take a deeper look into JEP 266, go over the improvements it has to offer and talk about one very interesting feature we bet will be one of the most used Java 9 features. Let’s go.
[Update 7-Feb-2018: Java 9 is here and is expected to revolutionize the way we think of and build large scale applications. Our Java 9 First Impressions webinar explores how.]
— OverOps (@overopshq) December 20, 2016
What’s Coming to Java 9
One of the JDK Enhancement Proposal (JEP) that Oracle drafted is JEP 266: More Concurrency Updates. While the name might sound like a snooze, it holds some updates that solve interesting problems in concurrency and parallelism, which require updates in those libraries.
According to the proposal, the changes and updates will be:
- Interfaces supporting the Reactive Streams publish-subscribe framework
- General improvements to the CompletableFuture API such as support for delays, timeouts, subclassing and other methods
- General improvements like small tweaks and javadoc spec rewording
We choose to focus on the first 2 bullets that hold some interesting plans inside (since general improvements are so… general).
The first thing we noticed is that Java 9 will support Reactive Streams. It’s an initiative that came out of the Java community, and it aims to improve concurrency workflows for developers. The second thing is a few fixer-uppers for the CompletableFuture API, that takes us back to the Future<T>.
But what does it actually mean? Well, we’re glad you asked.
Introducing Class Flow
The first update includes “Interfaces supporting the Reactive Streams publish-subscribe framework, nested within the new class Flow, along with a utility class SubmissionPublisher that developers can use to create custom components”.
Let’s start at the top. Reactive Streams solve the pain of back-pressure. The build-up of data that happens when the incoming tasks rate is higher than the system’s ability to process them, which result in a buffer of unhandled data.
We had a chat with Konrad Malawski, senior developer on Lightbend’s core Akka team that lead the Reactive Streams initiative, and he explained why it’s so important and how you can use it right now.
Oracle points out that the new enhancement will include “a very small interface that corresponds to those defined with broad participation (from the Reactive Streams initiative)”.
This is where the Flow class comes in. Reactive Streams is built of 4 Java interfaces:
The Flow class allows interrelated interfaces and static methods to establish flow-controlled components, in which Publishers produce items consumed by one or more Subscribers, each managed by a Subscription.
Reactive Streams is under the container class java.util.concurrent.Flow. In it you’ll find Flow.Publisher, a functional interface that is used as the assignment target for a lambda expression or a method reference. This interface will make it easier to produce elements for Flow.Subscription, that links the two together.
Another element here is the Flow.Subscriber, that works asynchronously and gets triggered by a request. It can request multiple elements from Flow.Subscription, and you can define the buffer size as you’d like.
These interfaces apply in both concurrent and distributed asynchronous settings, and the communication between them relies on a simple form of flow control, that can be used to avoid resource management problems.
You can check out some code examples for java.util.concurrent.Flow in the following link.
You don’t have to wait for Java 9 to try out the Reactive Streams interface, since some 3rd party libraries already implemented them. So you can check out the semantics before Java 9 will launch.
What’s New in CompletableFuture?
Java 8 brought us CompletableFuture, that implements Future<T>. Futures are useful when we don’t want or need an immediate result from a computation, and we receive a Future object that “holds the place” for the real result that will be assigned when the computation is done.
CompletableFuture has 2 main features that implement the Future object. It can be explicitly completed by calling the complete() method without any synchronous wait. And it allows building a pipeline data process in a series of actions.
That way, values of any type are available in the future with default return values, even if the computation didn’t complete, using default / intermediate results.
The updates that will be part of this proposal resolve some complaints that developers came across in Java 8. These include support for delays and timeouts, better support for subclassing, and a few utility methods.
If you want to know more about CompletableFuture and how it can make your code a little bit… futuristic, check out our full review of this feature right here.
Java 9 brought some major guns to the show, that include interesting methods and workflows that are bound to make Java better. We at OverOps think that JEP 266 is one of the most interesting updates, since it includes an initiative that came from the community itself, aiming to help developers solve some of the biggest issues with async stream processing. We’re all for it, and can’t wait for wider adoption of the new Java version!