Difference between a Future and a Mono
Asked Answered
J

2

15

In (Java) reactive programming, what is the difference between a Future<T> and a (Project Reactor) Mono<T>? Both seem to be means for accessing the result of an asynchronous computation at a time in the future when the computation is complete. Why introduce the Mono interface if Future already does the job?

Jac answered 17/1, 2019 at 15:7 Comment(1)
Maybe that helps: spring.io/blog/2016/04/19/understanding-reactive-types (first result for "java reactive mono vs future").Farrier
B
16

The greatest difference is that a Mono<T> can be fully lazy, whereas when you get hold of a Future<T>, the underlying processing has already started.

With a typical cold Mono, nothing happens until you subscribe() to it, which makes it possible to pass the Mono around in the application and enrich it with operators along the way, before even starting the processing.

It is also far easier to keep things asynchronous using a Mono compared to a Future (where the API tends to drive you to call the blocking get()).

Finally, compared to both Future and CompletableFuture, the composition aspect is improved in Mono with the extensive vocabulary of operators it offers.

Boley answered 23/1, 2019 at 13:9 Comment(1)
IOW, there's no real difference. From what I've seen, project reactor & spring tend to make up new names for well-known concepts. There's no reason why you couldn't have a implementation /extended interface of Future that supports the subscribe method, with a name that means something more meaningful than "1" or "Monkey".Rizika
R
5

Producer and consumer can communicate in 2 ways: synchronous and asynchronous.

In synchronous (pull-based) way, consumer is a thread and some intermediate communicator object is used. Usually it is a blocking queue. In special case, when only single value is passed during the whole producer-consumer communication, a communicator which implements interface Future can be used. This way is called synchronous, because the consumer calls communicating method like Future.get() and that methods waits until the value is available, and then returns that value as a result. That is, requesting the value, and receiving it, are programmed in the same statement, though these actions can be separated in time.

The drawback of synchronous communication is that when the consumer waits for the requested value, it wastes considerable amount of memory for it's thread stack. As a result, we can have only limited number of actions which wait for data. For example, it could be internet connections serving multiple clients. To increase that number, we can represent consumer not as a thread, but as some relatively small object, with methods called by the producer or communicator when datum for consumer is available. This way is called asynchronous. It is split in 2 actions: request to producer to pass data and passing that data to consumer. This is asynchronous (push-based) method.

Now the reply to the question is: Future is able to act as a synchronous communicator only (with get methods), and Mono can be used both as synchronous communicator (with block methods) and as an asynchronous one (with subscribe methods).

Note that java.util.concurrent.CompletableFuture can also act both as synchronous and asynchronous communicator. Why to have similar means to do the same thing? This phenomenon is called not invented here.

Roadside answered 17/1, 2019 at 16:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.