This is the fifth in a series of articles looking at some of the JDK Enhancement Proposals (JEPS) hoping to make their way into Java 9. Last week we looked at HTML5 and Javadoc.

This week we’re looking at JEP 266: More Concurrency Updates, which is required as “…the continual evolution of uses of concurrency and parallelism in applications requires continual evolution in library support.” The JEP includes an interoperable publish-subscribe framework, enhancements to the CompletableFuture API and other improvements such as Javadoc spec rewording.

An interoperable publish-subscribe framework

Reactive Streams

The Reactive Streams initiative provides a standard for asynchronous stream processing with non-blocking backpressure. It aims to solve the problem where elements are passed between threads or thread pools over time (the stream), and the receiving side gets varying amounts of data. If too much data comes in, the receiving side might become a bottleneck as it is still buffering the current data.

An example is events sent to an analytics engine to describe user interaction on a website. At peak times the number and size of events will increase, as more pages are viewed and links are clicked. If the receiver of the data doesn’t have the capacity to deal with incoming elements, future elements could be blocked until the existing ones are processed.

buffer overflow

Before sending more data, we could check whether or not the receiver is overwhelmed. However this makes the communication synchronous, and thus the benefits of an asynchronous system, e.g. parallel computation, is lost. The Reactive Streams initiative provides a specification that relies on ‘backpressure’ to ensure that the receiver isn’t overwhelmed by incoming data. It does this using flow control and the publish-subscribe pattern. It allows the subscriber to be intelligent about its capacity rather than act as a dumb receiver.

The publish-subscribe pattern

The publish-subscribe pattern is a messaging pattern. Publishers ‘publish’ information to multiple subscribers. Subscribers define which information they want to receive with a subscription, and are unaware of the publishers. To meet the goal of the Reactive Streams initiative and achieve non-blocking backpressure, the subscriber controls the number of elements it will receive. It does this by requesting a certain number of elements at a time. This is a pull strategy as the subscriber is requesting messages rather than having messages pushed to it.

Java 9: Flow interfaces

The JEP provides interfaces that support the publish-subscribe Reactive Streams framework. This facilitates the creation of a Flow.Publisher, which produces elements for a Flow.Subscription. The Flow.Subscription links the Flow.Publisher to a Flow.Subscriber.

Publication to the Flow.Subscriber is asynchronous and is triggered by a request. The Flow.Subscriber requests the elements from the Flow.Subscription using Flow.Subscription.request(long). It then processes the elements. It can request multiple elements, and a buffer size can be defined.

For more information and code examples, see the class Flow.

 

Enhancements to the CompletableFuture API

A Future “represents the result of an asynchronous computation”. A CompletableFuture is a Future that can be explicitly completed: it has a CompletionStage that allows function and actions to be triggered when it has finished. It was introduced in Java 8 and is well described in Asynchronous Programming in Java 8: How to Use CompletableFuture.

The changes in Java 9 include:

  • Support for delays and timeouts
  • Better support for subclassing

It will also have a few new utility methods. These are to address common complaints and suggestions since the Java 8 introduction.

 

Further reading

See A Journey into Reactive StreamsBuilding Microservices with Vert.x and Building a multiplayer game using Reactive Streams for more information on reactive streams.

See also the Reactive Streams JVM specification.

 

Next up: Variable Handles