Java 9 Flow API example - Publisher and Subscriber » grokonez

Java 9 Flow API example - Publisher and Subscriber » grokonez

In this tutorial, we're gonna look at Java 9 Flow api example that implements Publisher and Subscriber for reactive programming.

Java 9 Flow API example – Publisher and Subscriber

In previous post, we have general knowledge about Reactive Streams and Java 9 Flow API Components and Behaviour. In this tutorial, we're gonna look at an example that implements Publisher and Subscriber for reactive programming.

Related Articles:

I. Technologies

- Java 9 - Eclipse with Java 9 Support for Oxygen (4.7)

II. Project Overview

We will create a Publisher that is subscribed by two Subscribers. - Publisher maintains a list of Subscriptions, each Subscription is correlative to each Subscriber above. - Publisher uses one Subscription to push items to correlative Subscriber by Subscriber::onNext() method. - Subscriber uses Subscription to request items from Publisher by Subscription::request() method. - Publisher defines an Executor for multi-threading. Then request() and onNext() method work asynchronously, producing data to each Subscriber by Subscription is also asynchronous. - After receiving all items successfully, Subscriber can request new data or cancel Subscription (random).

III. Practice

To understand how Publisher, Subscriber and Subscription behave and way to implementing them, please visit: Java 9 Flow API – Reactive Streams

1. Create implementation of Publisher

package com.javasampleapproach.java9flow.pubsub;

import static java.lang.Thread.currentThread; import static java.util.concurrent.Executors.newSingleThreadExecutor;

import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Flow.Publisher; import java.util.concurrent.Flow.Subscriber; import java.util.concurrent.Flow.Subscription; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger;

public class MyPublisher implements Publisher {

private static final String LOG_MESSAGE_FORMAT = "Publisher >> [%s] %s%n";

final ExecutorService executor = Executors.newFixedThreadPool(4);
private List<MySubscription> subscriptions = Collections.synchronizedList(new ArrayList<MySubscription>());

private final CompletableFuture<Void> terminated = new CompletableFuture<>();

public void subscribe(Subscriber<? super Integer> subscriber) {
    MySubscription subscription = new MySubscription(subscriber, executor);



public void waitUntilTerminated() throws InterruptedException {
    try {
    } catch (ExecutionException e) {

private class MySubscription implements Subscription {

    private final ExecutorService executor;

    private Subscriber<? super Integer> subscriber;
    private final AtomicInteger value;
    private AtomicBoolean isCanceled;

    public MySubscription(Subscriber<? super Integer> subscriber, ExecutorService executor) {
        this.subscriber = subscriber;
        this.executor = executor;

        value = new AtomicInteger();
        isCanceled = new AtomicBoolean(false);

    public void request(long n) {
        if (isCanceled.get())

        if (n < 0)
            executor.execute(() -> subscriber.onError(new IllegalArgumentException()));

    public void cancel() {

        synchronized (subscriptions) {
            if (subscriptions.size() == 0)

    private void publishItems(long n) {
        for (int i = 0; i < n; i++) {

            executor.execute(() -> {
                int v = value.incrementAndGet();
                log("publish item: [" + v + "] ...");

    private void shutdown() {
        log("Shut down executor...");
        newSingleThreadExecutor().submit(() -> {

            log("Shutdown complete.");


private void log(String message, Object... args) {
    String fullMessage = String.format(LOG_MESSAGE_FORMAT, currentThread().getName(), message);

    System.out.printf(fullMessage, args);


2. Create implementation of Subscriber

More at:

Java 9 Flow API example – Publisher and Subscriber

java java9 publiser subscriber flow

What is Geek Coin

What is GeekCash, Geek Token

Best Visual Studio Code Themes of 2021

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

How to Install OpenJDK 11 on CentOS 8

What is OpenJDK? OpenJDk or Open Java Development Kit is a free, open-source framework of the Java Platform, Standard Edition (or Java SE).

Going Beyond Java 8: Local Variable Type Inference (var) - DZone Java

In this article, we will talk about the most important new feature introduced with Java 10, officially called local variable type inference. An extremely important function in java. You will regret skipping this article.

Java Online Training | Java Online Course | ITGuru

Our Java Online Training provide you to learn about Java programming and its different features with realty. Our Java Online Course includes live sessions, live projects

Spring Boot and Java 16 Records

In this article, we will discuss Java 16's newest feature, Records. Then we will apply this knowledge and use it in conjunction with a Spring Boot application. An extremely important function in java. You will regret skipping this article.

Java Development Company in USA | Java Application Development Company

We offer java app development & web app services at affordable rates. Let our Java Developers customize for you to provide high performance & reliable Java based solutions.