

Table of Contents
Reactive streams:
Reactive Streams aims to improve concurrency workflows for developers by solving the pain of back-pressure (when fast data source doesn’t overwhelm the stream destination).
In the image above, we can see that if Destination can not deal with incoming data from Source, all future data could be blocked until the existing ones are processed.
Reactive Streams processes an asynchronous stream data across an asynchronous boundary (passing elements on to another thread or thread-pool), and receiving side (Destination) is not forced to buffer arbitrary amounts of data, then buffer overflow will not occur.
In summary, Reactive Streams:
– process a potentially unbounded number of elements
– in sequence,
– asynchronously passing elements between components,
– with mandatory non-blocking back-pressure.
Reactive programming:
“Reactive programming is about processing an asynchronous stream of data items, where applications react to the data items as they occur. A stream of data is essentially a sequence of data items occurring over time. This model is more memory efficient because the data is processed as streams, as compared to iterating over the in-memory data.”
The main problem is Handling streams of data—especially “live” data whose volume is not predetermined—requires special care in an asynchronous system. The most prominent issue is that resource consumption needs to be controlled such that a fast data source does not overwhelm the stream destination.
The Flow Api:
Java 9 comes with one handy feature called Flow API or reactive API. It has four basic components as below.
- Publisher
- Subscriber
- Subscription
- Processor
Java 9 provide java.util.concurrent.Flow class whichprovidese reactive stream publish subscribe framework. It contains Interrelated interfaces and static methods for establishing flow-controlled components as below.
@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> { }
Now let’s discuss each components in brief.
Publisher:
The publisher publishes the stream of data items to the registered subscribers. It publishes items to the subscriber asynchronously, normally using an Executor.
Each Subscribes receives the same items in the same order,unless drops or errors are encountered.
Publishers ensure that subscriber method invocations for each subscription are strictly ordered.
Subscriber:
Subscriber is a receiver of messages.
Data items are not pushed to the Subscriber unless requested, but multiple items may be requested. Subscriber method invocations for a given Subscription are strictly ordered.
Subscription:
Message control linking a Flow.Publisher
and Flow.Subscriber
. Subscribers receive items only when requested, and may cancel at any time.
Processor:
A component that acts as both a Subscriber and Publisher.
The processor sits between the Publisher and Subscriber, and transforms one stream to another. There could be one or more processor chained together, and the result of the final processor in the chain, is processed by the Subscriber.
We can create one or more Processors in chain which link a Publisher to a Subscriber.
General Flow:
Now look at the diagram below:
Publisher uses its subscribe()
method with Subscriber object as input parameter. That Subscriber now subscribes the Publisher.
Publisher defines its own Subscription implementation and produces data elements for that Subscription.
When a Subscriber subscribes a Publisher, onSubscribe()
method is invoked. Then Subscriber now can use Subscription to link to the Publisher by request(numberItems)
or cancel()
method.
Publisher uses Subscription to invoke Subscriber‘s methods:
onNext()
if publishing items to the Subscriber asynchronously, normally using an Executor
.
onComplete()
when no more elements are available,
onError()
if there is a failure.
Refer Reactive Prgramming , JEP-266 and Flow for more details.