The Java 9 Flow API
Oracle Corporation has introduced a new API for library or API developers to develop Reactive systems, Reactive libraries, Reactive data stores, Reactive servers, and so on. This API is also known as the Flow API.
It defines a set of interfaces to support developing Reactive systems, so it is also known as the Reactive Streams API. This API is defined under the java.util.concurrent
package name.
The Java 9 Flow API mainly contains the following components:
- Publisher
- Subscriber
- Subscription
- Processor
- Flow
The following diagram shows the main five components of the Java 9 Flow API:

Let's discuss these components of the Flow API one by one in detail in the following sections.
Flow API – Publisher
As its name suggests, Publisher is a component that works as a Producer of data, which means it emits the data. It acts as a source of data, so it is also known as Producer, Source of data, or emitter:

In the Java 9 Flow API, this Publisher
is an interface with the subscribe
method and is defined with the following signature:
public interface Publisher<T> { public void subscribe(Subscriber<? super T> subscriber); }
Here, the subscribe()
method is taking a single parameter of type Subscriber
, which is another component of the Flow API. One publisher can subscribe one or more subscribers to it. It is defined within another class as a static component. We will see it in the following section.
Publisher uses this subscribe()
method to subscribe or register its subscribers, as shown here.
Go through the following pseudo-code for Subscriber.subscribe()
function usage:
Subscriber sub = Receive a Request from a Subscriber Publisher pub = ... pub.subscribe(sub)
Publisher receives a request from a subscriber and executes pub.subscribe(sub)
to register that subscriber with it. Once that subscription is created, the publisher sends data to those registered parties.
For instance, we can use a data store, file, collection, server, and more, as a source of data to emit data for subscribers.
Flow API – Subscriber
As its name says, the Subscriber is a component that works as a consumer of data. This means it consumes the data from a producer. It acts as a destination of data. So, it is also known as a consumer or destination of data:

In the Java 9 Flow API, this Subscriber
is an interface with a set of methods and is defined as follows:
public static interface Subscriber<T> { public void onSubscribe(Subscription subscription); public void onNext(T item); public void onError(Throwable throwable); public void onComplete(); }
It has a set of methods:
onSubscribe()
: This creates a new subscription. It is invoked prior to invoking any otherSubscriber
methods for the given Subscription.onNext()
: Once a Subscription is created, this is invoked to receive the next data, item, or element from the Publisher.onError()
: This is invoked upon an unrecoverable error encountered by a Publisher or Subscription, after which no otherSubscriber
methods are invoked by the Subscription.onComplete()
: This is invoked when there is no requirement to invoke any furtherSubscriber
methods on that Subscription that is not already terminated in error, after which no otherSubscriber
methods are invoked by that Subscription.
It is also defined within another class as a static component. We will see it in the next section.
Flow API – Subscription
In the Flow API, a Subscription works as a mediator or interface between two other important components, Publisher and Subscriber. It connects those components and works as a message controller or channel so that a Publisher can emit data into a Subscription and one or more subscribers who subscribe to that Publisher and receive data from that Subscription:

In the Java 9 Flow API, this Subscription
is an interface with a set of methods and is defined as follows:
public static interface Subscription { public void request(long n); public void cancel() ; }
It contains the following two methods to control the messaging between Publisher and Subscriber(s):
request()
: This is used to add the given n number of items to the current active Subscription between Publisher and Subscriber(s)cancel()
: This is used to cancel or stop the current Subscription between Publisher and Subscriber(s) so that there is no communication happening between them
One Subscription is dedicated between a Publisher and a single Subscriber or a set of Subscribers. Once it's stopped by making a call to the cancel()
method, Publisher cannot send data to it or Subscriber cannot receive any messages from it.
It is also defined within another class as a static component. We will see it in the next section.
Flow API – Processor
In the Flow API, Processor is a special kind of component. It works as both a Subscriber and Publisher. We can use it as a source of data, that is, a Publisher, or a destination of data, that is, a Subscriber.
In the Java 9 Flow API, this Processor
is an interface with no methods and is defined like this:
public interface Processor<T,R> extends Subscriber<T>, Publisher<R> { }
It is also defined within another class as a static component. We will see it in the next section.
Flow API – Flow
In the previous sections, we discussed the components of the Flow API one by one in depth. They are all interfaces and are defined as static components within another component of the Flow API. This component is Flow
.
In the Java 9 Flow API, this Flow
component contains the rest of the four components' static components, as shown here:
Flow.java:
package java.util.concurrent; public final class Flow { private Flow() {} @FunctionalInterface public static interface Publisher<T> { public void subscribe(Subscriber<? super T> subscriber); } public static interface Subscriber<T> { public void onSubscribe(Subscription subscription); public void onNext(T item); public void onError(Throwable throwable); public void onComplete(); } public static interface Subscription { public void request(long n); public void cancel(); } public static interface Processor<T,R> extends Subscriber<T>, Publisher<R> { } static final int DEFAULT_BUFFER_SIZE = 256; public static int defaultBufferSize() { return DEFAULT_BUFFER_SIZE; } }
This is so that we can access other components as Flow.xxxx
, which means if we want to access a Publisher, we should use it like Flow.Publisher
.
When we combine or connect all these components in a working system, we will see them as follows:

When we connect the Flow API components in this way, we can observe that a flow is going from source to destination. That's why they have named this API as the Flow API.
We can represent the Java 9 Flow API's Publisher/Subscriber complete communication as shown in the following diagram. This communication can end either successfully or in failure:
