liveBook · Manning

subscribeOn

As explained in Spring in Action, Sixth Edition

subscribeOn is a Project Reactor operator that specifies the scheduler on which subscription and upstream work are performed.

`subscribeOn()` tells Project Reactor which scheduler should handle a subscription. It does not start the reactive flow: `subscribe()` does that. Use `subscribeOn(Schedulers.parallel())` when subscriptions should run on workers from a fixed-size pool. section 11.3.3

Transform names in parallel

Start with a `Flux` of names. For each name, `flatMap()` creates a `Mono`, maps the name to a `Player`, and applies `subscribeOn(Schedulers.parallel())` to that inner `Mono`. The individual mappings can then run asynchronously and in parallel, and `flatMap()` combines their results into one `Flux<Player>`. Unlike the synchronous `map()` version, do not rely on the players arriving in source order. section 11.3.3

@Test
public void flatMap() {
  Flux<Player> playerFlux = Flux
    .just("Michael Jordan", "Scottie Pippen", "Steve Kerr")
    .flatMap(n -> Mono.just(n)
        .map(p -> {
            String[] split = p.split("\\s");
            return new Player(split[0], split[1]);
          })
        .subscribeOn(Schedulers.parallel())
      );
  
  List<Player> playerList = Arrays.asList(
      new Player("Michael", "Jordan"), 
      new Player("Scottie", "Pippen"), 
      new Player("Steve", "Kerr"));
 
  StepVerifier.create(playerFlux)
      .expectNextMatches(p -> playerList.contains(p))
      .expectNextMatches(p -> playerList.contains(p))
      .expectNextMatches(p -> playerList.contains(p))
      .verifyComplete();
}

The test shows where to place `subscribeOn()` in each inner `Mono` and verifies the resulting players without requiring a fixed order. section 11.3.3

Table 11.1 Concurrency models for Schedulers (view table figure)

Schedulers method

Description

.immediate()

Executes the subscription in the current thread.

.single()

Executes the subscription in a single, reusable thread. Reuses the same thread for all callers.

.newSingle()

Executes the subscription in a per-call dedicated thread.

.elastic()

Executes the subscription in a worker pulled from an unbounded, elastic pool. New worker threads are created as needed, and idle workers are disposed of (by default, after 60 seconds).

.parallel()

Executes the subscription in a worker pulled from a fixed-size pool, sized to the number of CPU cores.

Compare `parallel()` with the other available scheduler choices before selecting how subscriptions should run. section 11.3.3

How Spring in Action, Sixth Edition covers it

How deep it goes
Explains subscription scheduling through a worked test and compares scheduler choices, without detailing scheduler internals.
Examples
Transforms a Flux of player names into Player objects and verifies the results with StepVerifier.
What it assumes
Assumes familiarity with Java lambdas and Flux/Mono chains while explaining how subscribeOn differs from subscribe.
What you can do after
Apply it via Project Reactor to select a scheduler for subscriptions within a flatMap transformation.
How it connects
Connects flatMap, Mono, Flux, map, subscribe, and Schedulers through asynchronous stream transformation.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring in Action, Sixth Edition. The section links point to the parts of the book it draws on.