We use the subscribeOn and publishOn operators for switching the execution context (Scheduler) in a reactive chain.
In the previous lesson, we mentioned that the default behavior is that the same thread that performs a subscription will be used for the whole pipeline execution.
Let’s see one simple example:
class ReactiveJavaTutorial { public static void main(String[] args) { Flux<String> cities = Flux.just("New York", "London", "Paris", "Amsterdam") .map(String::toUpperCase) .filter(cityName -> cityName.length() <= 8) .map(cityName -> cityName.concat(" City")) .log(); cities.subscribe(); }
The subscribeOn() method
The subscribeOn() method applies to the subscription process. We can place it anywhere in the reactive chain. It accepts Scheduler and picks up the thread from the provided thread pool.
For this example, we use a bounded elastic thread pool (Schedulers.boundElastic()). See the previous lesson for more on the Scheduler options.
Example
class ReactiveJavaTutorial { public static void main(String[] args) { Flux<String> cities = Flux.just("New York", "London", "Paris", "Amsterdam") .subscribeOn(Schedulers.boundedElastic()) .map(String::toUpperCase) .filter(cityName -> cityName.length() <= 8) .map(cityName -> cityName.concat(" City")) .log(); cities.subscribe(); } }
The publishOn() method
The publishOn() method is similar to the subscribeOn(), but there is one main difference.
First, let’s see one example:
class ReactiveJavaTutorial { public static void main(String[] args) { Flux.just("New York", "London", "Paris", "Amsterdam") .map(ReactiveJavaTutorial::stringToUpperCase) .publishOn(Schedulers.boundedElastic()) .map(ReactiveJavaTutorial::concat) .subscribe(); } private static String stringToUpperCase(String name) { System.out.println("stringToUpperCase: " + Thread.currentThread().getName()); return name.toUpperCase(); } private static String concat(String name) { System.out.println("concat: " + Thread.currentThread().getName()); return name.concat(" City"); } }
Here, we placed the publishOn() between the two map operators. Let’s see the output:
stringToUpperCase: main stringToUpperCase: main stringToUpperCase: main concat: boundedElastic-1 concat: boundedElastic-1 concat: boundedElastic-1
Everything before the publishOn operator was executed by the main thread and everything after by the boundedElastic-1 thread. That is because the publishOn acts as any other operator. It takes signals from upstream and replays them downstream while executing the callback on a worker from the associated Scheduler.
That is the main difference between the subscribeOn and publishOn operators since the subscribeOn will apply the provided Scheduler to the whole reactive chain, no matter where we placed it.
That was all about how to switch threads in Project Reactor. Proceed to the next lesson.
Happy coding!