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.
A 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.