the Subscription
plays a pivotal role in managing flow control and resource management in reactive programming.
Let’s break it down 👇
🎯 What is a Subscription
?
In Reactive Streams (Java 9 Flow API, RxJava, Reactor, Akka Streams), a Subscription
is the link between the Publisher (data producer) and the Subscriber (data consumer).
It gives the Subscriber control over:
- How much data to receive (
request(n)
) - When to stop receiving (
cancel()
)
Think of it like a remote control 📺:
The subscriber can press “Give me more” or “Stop” at any time.
🧩 Core Responsibilities of Subscription
Method | Purpose |
---|---|
request(long n) | Tells the Publisher: “I’m ready for n more items.” This enables backpressure. |
cancel() | Stops the data flow and unsubscribes the observer. Useful for cleanup and preventing memory leaks. |
🧪 Example: Manual Control
import java.util.concurrent.Flow.*;
public class CustomReactiveFlow {
public static void main(String[] args) {
Publisher<Integer> publisher = subscriber -> {
subscriber.onSubscribe(new Subscription() {
int count = 0;
boolean cancelled = false;
@Override
public void request(long n) {
for (int i = 0; i < n && !cancelled; i++) {
subscriber.onNext(count++);
}
subscriber.onComplete();
}
@Override
public void cancel() {
cancelled = true;
System.out.println("Subscription cancelled");
}
});
};
Subscriber<Integer> subscriber = new Subscriber<>() {
private Subscription subscription;
@Override
public void onSubscribe(Subscription s) {
this.subscription = s;
System.out.println("Subscribed");
s.request(5); // ask for 5 items
}
@Override
public void onNext(Integer item) {
System.out.println("Received: " + item);
}
@Override
public void onError(Throwable t) {}
@Override
public void onComplete() {
System.out.println("Done");
}
};
publisher.subscribe(subscriber);
}
}
🧠 Why is Subscription
So Important?
✅ Backpressure: Without request(n)
, fast publishers can overwhelm slow consumers.
✅ Laziness: Publishers don’t start emitting until request()
is called — promotes efficiency.
✅ Cancellation: Prevents memory leaks and unnecessary computation.
✅ Resource management: Like closing files, sockets, or unsubscribing from events.
🔗 Where You See Subscription
Library | Role of Subscription |
---|---|
Java Flow API | Manual request() and cancel() |
RxJava | Abstracted as Disposable |
Project Reactor | Implicit with BaseSubscriber , or accessed via .doOnSubscribe(...) |
Spring WebFlux | Automatically handled — but still honors request(n) from clients |
Akka Streams | Backpressure protocol handled under the hood via demand signaling |
🧠 Why is Subscription
So Important?
✅ Backpressure: Without request(n)
, fast publishers can overwhelm slow consumers.
✅ Laziness: Publishers don’t start emitting until request()
is called — promotes efficiency.
✅ Cancellation: Prevents memory leaks and unnecessary computation.
✅ Resource management: Like closing files, sockets, or unsubscribing from events.
🔗 Where You See Subscription
Library | Role of Subscription |
---|---|
Java Flow API | Manual request() and cancel() |
RxJava | Abstracted as Disposable |
Project Reactor | Implicit with BaseSubscriber , or accessed via .doOnSubscribe(...) |
Spring WebFlux | Automatically handled — but still honors request(n) from clients |
Akka Streams | Backpressure protocol handled under the hood via demand signaling |