Skip to content

Mono subscribe vs block differences

  • by
Mono subscribe vs block

1. Overview

In this article, we will learn the difference between Mono subscribe vs block. To know about Mono or Flux reactive stream, refer to this article.

Mono is a publisher that emits a single value or an empty (0..1) result (at most a single element).

As you know, Mono is an asynchronous call that executes in a non-blocking way.

2. Mono subscribe vs block differences

The block() call explicitly blocks the main or the caller thread until the publisher (Mono) completes. You must avoid this method as this has the potential to lock your whole reactive pipeline. 

The subscribe method signals the publisher for the data and executes on the same thread as the caller by default.

System.out.println("Thread : " + Thread.currentThread().getName());

Mono<Integer> optionalMono = Mono.just(1000);
optionalMono
     .subscribe(result -> {
       try {
            Thread.sleep(5000);
       } catch (InterruptedException e) {
            e.printStackTrace();
       }
       System.out.println("subscribe thread : " + Thread.currentThread().getName());
});

System.out.println("Thread : " + Thread.currentThread().getName() + " is leaving");

The preceding code prints the following logs on the console. As you can see, subscribe executes on the same caller thread.

Thread : reactor-http-nio-2
subscribe thread : reactor-http-nio-2
Thread : reactor-http-nio-2 is leaving

You can use the subscribeOn to specify the Scheduler so that both the subscribe and the upstream Mono publisher executes on a dedicated thread provided by the Scheduler. To know more about the subscribeOn, refer to this article.

2.1. Mono block

You can use the block() method to block the caller or main thread indefinitely and wait for Mono to complete. If the Mono completes, then this method either returns the original value or null (Mono is empty).

In case of any errors, then the exception is rethrown.

Mono<String> getMono() {
    return Mono.just("Example of Mono");
}

String result = getMono().block();
System.out.println(result);

2.1.1. Mono Block with a timeout

Rather than waiting indefinitely for the Mono to complete using the block() method, you can specify a maximum timeout to wait for the result:

public T block(Duration timeout)

The above block method accepts timeout duration as input and waits until the Mono completes or the timeout expires. It throws a RuntimeException when the timeout expires.

String result = getMono().block(Duration.ofMillis(10000));
System.out.println(result);

2.1.2. Mono blockOptional

If the Mono completes, then the block method returns the original value or null if empty. Instead of getting null value, you can get Optional<String> by using the blockOptional method.

Optional<String> result = Mono.<String>empty().blockOptional();

3. How Mono subscribe differ from block

You can retrieve the result from Mono in a non-blocking way by the act of subscribing that will consume all the sequences. See this article on Mono subscribe() for more detailed information.

Disposable subscribe(Consumer<? super T> consumer) 

For example, the following subscribe method prints the result of Mono to the console.

getMono()
    .subscribe(System.out::println);

You can use the returned Disposable instance to cancel the subscription.

Disposable disposable = getMono()
    .subscribe(System.out::println);

disposable.dispose();

You can also subscribe for errors that can happen during Mono execution.

getMono().subscribe(result -> System.out.println(result.toUpperCase()),
				error -> System.out.println(error.getMessage()));

4. Conclusion

To sum up, we have learned the differences between Mono subscribe vs block methods.  You can get samples discussed in this article from our GitHub repository.

Leave a Reply

Your email address will not be published. Required fields are marked *