🕐 Reading time: 2 minutes

It's been a first season of articles that entertained me and taught me a lot; after today's appointment, Java Pills will take a summer break and return in September!

Let's close the season with the second part of pill #17, focusing on .share(), to handle multiple concurrent subscribers effectively.

📌 Cold stream vs hot shared

When several subscribers subscribe to the same Flux at almost the same moment, the default behaviour – being cold – is to re-run the logic for each one. With .share(), instead, the Flux becomes hot:

📑 The test (yes, it's a bit convoluted)

@Test
void test_buildFlux_withShare() throws InterruptedException {
    final AtomicInteger subscriptionCount = new AtomicInteger();
    //create a cold Flux that emits "A", "B", "C" and increments the counter on each new subscription
    final Flux<String> sharedFlux = buildFlux(subscriptionCount)
            .delayElements(Duration.ofMillis(100)) //simulate delay to keep the Flux active
            .share();                              //share the source among concurrent subscribers

    final List<String> result1 = new ArrayList<>();
    final List<String> result2 = new ArrayList<>();
    final CountDownLatch latch = new CountDownLatch(2); //to wait for both subscriptions to finish

    subscribeAsync(sharedFlux, result1, latch);
    subscribeAsync(sharedFlux, result2, latch);

    assertTrue(latch.await(2, TimeUnit.SECONDS)); //wait for both subscriptions to complete
    checkResults(result1, result2);
    //expect <1> because the subscription is shared among concurrent subscribers
    assertEquals(1, subscriptionCount.get());
}

//start both subscriber threads (they will subscribe almost simultaneously) in separate threads
private void subscribeAsync(final Flux<String> sharedFlux, final List<String> result, final CountDownLatch latch) {
    new Thread(() -> sharedFlux.collectList()
            .doOnNext(result::addAll)               //collect the emitted values
            .doFinally(signal -> latch.countDown()) //signal when done
            .block())                               //block until the Flux completes
        .start();
}

What happens in the test:

📌 When is it worth using share?

⚠️ Limits and things to watch out for

See you in September with the next pill! ☕