In this article, we will dive into Reactive programming in Java, especially we have to understand about its architecture. Based on it, we can easily apply them into utilizing some frameworks such as RxJava, Reactor, …
Let’s get started.
Table of contents
- What is Reactive programming ?
- Reactive architecture
- How does Java implement Reactive programming ?
- Benefits and Drawbacks
- Some interview questions
- Wrapping up
What is Reactive programming ?
In a modern web application, response speed or the latency proprety is an important property to make user come back with your website, beside UI - User Interface, UX - User Experience.
When a user send a request to server such as get all cell phones’s information for specific type, we have two ways to deal with it:
-
Synchronous approach: Keep the user waiting util the result has not been processed to find the list of the cell phones that will be fetched from the database.
-
Asynchronous approach: Allow the user to proceed further and use other stuff in the application, such as finding cell phone details, availability of items, and so on.
So, easily our reactive programming will be using asynchronous approach.
Reactive architecture
In Reactive concept, we use a publisher - subscriber mechanism. It can be described with the following ideas:
-
A
subscriberinforms apublisherthat it is willing to accept a given number of items (requests a given number of items), and if items are available, thepublisherpushes the maximum receivable number of items to thesubscriber.It is important to note that this is a two-way communication, where the subscriber informs the publisher how many items it is willing to handle and the publisher pushes that number of items to the subscriber.
-
The process of restricting the number of items that a
subscriberis willing to accept (as judged by thesubscriberifself) is calledbackpressureand is essential in prohibiting the overloading of thesubscriber(pushing more items that thesubscribercan handle).
The two-way connection between a
publisherand asubscriberis called asubscription. Thissubscriptionbinds a singlepublisherto a singlesubscriber(one-to-one relationship) and may be unicast or multicast.A single
subscribersubscribe to apublisher, thepublishernotifies thesubscriberof the subscription that was created, allowing thesubscriberto store a reference to thesubscription(if desired). Once this notification process is completed, thesubscribercan inform thepublisherthat it is ready to receive some n number of items. -
When the
publisherhas items available, it then sends at most n number of items to thesubscriber. If an error occurs in thepublisher, it signals thesubscriberof the error. If thepublisheris permanently finished sending data, it signals thesubscriberthat it is complete. If thesubscriberis notified that either an error occurred or thepublisheris complete, thesubscriptionis considered canceled and no more interactions between thepublisherandsubscriber(or thesubscription) will take place.This
subscriptionworkflow will be illustrated in the figure below.
It is important to note that there are two theoretical approaches to streaming data to a
subscriber.-
The
subscriptionholds the itemsThe
publisherpushes items to thesubscriptionwhen they become available; when, at a later time, thesubscriberrequests n items, thesubscriptionprovides n or fewer items it has previously been given by thepublisher. This may be used when thepublishermanages queued items, such as incoming HTTP requests. -
The
publisherholds the items.The
subscriberforwards requests to thepublisher, which pushes n or fewer items to thesubscription, which in turn pushes those same items to thesubscriber. This scenario may be more suitable for instances were items are generated as needed, such as with a prime number generator.
It is also important to note that items do not have to be present before a request can be made. If a
subscribermakes a request for n items and no items are available, thesubscriberwill wait until at least one item is available and is pushed to thesubscriber. If there are i items available when thesubscribermakes a request for n items, where i is less than n, the i items are pushed to thesubscriber. Once j more items are available, n - i items of the j items are also pushed to thesubscriberuntil n number of total items have been pushed to thesubscriber(i + j = n), or thesubscriberhas requested m more items; in this case, all j number of items may be pushed to thesubscriberso long as i + j is less than or equal to n + m. The number of items that asubscribercan accept at any given time (which may or may not be equal to n, depending on the number of items already pushed to thesubscriber) is called theoutstanding demand.For example, suppose a
subscriberrequests 5 items and 7 are currently available items in thepublisher. The outstanding demand for the subscriber is 5 so 5 of the 7 items are pushed to thesubscriber. The remaining 2 items are maintained by thepublisher, awaiting thesubscriberto request more items. If thesubscriberthen requests 10 more items, the 2 remaining items are pushed to thesubscriber, resulting in an outstanding demand of 8. If 5 more items become available in thepublisher, these 5 items are pushed to thesubscriber, leaving an outstanding demand of 3. The outstanding demand will remain at 3 unless thesubscriberrequests n more items, in which case the outstanding demand will increase to 3 + n, or more i items are pushed to thesubscriber, in which case the outstanding demand will decrease to 3 - i (to a minimum of 0). -
How does Java implement Reactive programming ?
In Reactive programming, Reactive Stream is a center concept, it completely boosts the performance of the stream of java.
There are many libraries that implement the Reactive Stream specification. They support Reactive programming such as:
- Akka
- Reactor
- RxJava
- Streams
- Ratpack
- Vert.x.
Because of Spring that is utilizing Reactor library to implement reactive streams, so we will see Reactor will contain which elements in it.
Below is some parts of Reactor library:

-
Publisher
According to http://www.reactive-streams.org about Publisher, we have:
- A Publisher is a provider of a potentially unbounded number of sequenced elements, publishing them according to the demand received from its Subscribers.
- A Publisher can serve multiple Subscribers subscribed
public interface Publisher<T> { // request Publisher to start streaming data // This is a factory method, and can be called multiple times, each time starting a new Subscription. // Each Subscription will work for only a single Subscriber. void subscribe(Subscriber<? super T> s); } -
Subscriber
According to http://www.reactive-streams.org about Subscriber, we have:
- Will receive call to
onSubscribe(Subscription)once after passing an instance of Subscriber toPublisher.subscribe(Subscriber). - No further notifications will be received until
Subscription.request(long)is called.
public interface Subscriber<T> { // successful terminal state void onComplete(); // failed terminal state void onError(Throwable t); // data notification sent by the Publisher in response to requests to Subscription.request(long) void onNext(T t); // invoked after calling Publisher.subscribe(Subscriber) void onSubscribe(Subscription s); } - Will receive call to
-
Subscription
According to http://www.reactive-streams.org, we have:
- A Subscription represents a one-to-one lifecycle of a Subscriber subscribing to a Publisher.
- It can only be used once by a single Subscriber.
- It is used to both signal desire for data and cancel demand (and allow resource cleanup).
public interface Subscription { // request the Publisher to stop sending data and clean up resources void cancel(); // no events will be sent by a Publisher until demand is signaled via this method void request(long n); }
Benefits and Drawbacks
-
Benefits
- It increases the performance of the application.
- It increases the utilization of computing resources on a multicore.
- It provides a more maintainable approach to deal with asynchronous programming.
- It includes back pressure, which plays a vital role to avoid over-utilization of the resources.
Because:
- Reactive system supports parallel programming to avoid blocking of the resources in order to utilize the hardware to its fullest.
Some interview questions
-
Flux<T>finite collection or infinite stream?It depends on media type to decide.
-
application/json–> finite collection (JSON array)No back-pressure, Flux#collectToList (request all + buffer)
-
text/event-stream,application/stream+json–> infinite streamBack-pressure with request(n), write, flush, repeat.
-
Wrapping up
-
Before Java 8, asynchronous non-blocking behavior was not obvious to implement for at least two reasons.
- Callback based API required verbose anonymous classes and are not easy to chain.
Futuretype is asynchronous but blocks the current thread until the computation completes when we try to get the result with theget()method.
-
Netty server
- Monolithic: 200-300 requests/sec/host
- Reactive: 10-20k requests/sec/host
-
Reactor project allows building high performance (low latency, high throughput) non-blocking asynchronous applications on JVM.
Reactor is desgined to be extraordinarily fast and can sustain throughput rates on order of 10’s of millions of operations per second.
Make uses of the concept of Mechanical Sympathy built on top of Disruptor / RingBuffer.
https://dzone.com/articles/reactive-streams-in-java-9
https://www.slideshare.net/InfoQ/servlet-vs-reactive-stacks-in-five-use-cases