既然 Reactive Stream 和 Java 8 引入的 Stream 都叫做流,它们之间有什么关系呢?有一点关系,Java 8 的 Stream 主要关注在流的过滤,映射,合并,而 Reactive Stream 更进一层,侧重的是流的产生与消费,即流在生产与消费者之间的协调。
在进行异步消息处理时,Reactive Streams 和 Actor 是两种不同的编程模式选择。Reactive Streams 规范相比 Actor 更简单,只是说收发消息异步,有流量控制。而 Actor 编程模式涉及到 Actor 容错管理,消息路由,集群,并支持远程消息等。
还有共同之处是: 它们定义的 API 都很简单,编码时都基本不需要关注线程本身,而实际消息的传递都是背后的线程池。所以线程的配置可延迟到部署阶段来进行优化处理。
1. 由推变拉,数据可多次消费
Asynchronous processing decouples I/O or computation from the thread that invoked the operation. A handle to the result is given back, usually a java.util.concurrent.Future
or similar, that returns either a single object, a collection or an exception. Retrieving a result, that was fetched asynchronously is usually not the end of processing one flow. Once data is obtained, further requests can be issued, either always or conditionally. With Java 8 or the Promise pattern, linear chaining of futures can be set up so that subsequent asynchronous requests are issued. Once conditional processing is needed, the asynchronous flow has to be interrupted and synchronized. While this approach is possible, it does not fully utilize the advantage of asynchronous processing.
In contrast to the preceding examples, Publisher<T>
objects answer the multiplicity and asynchronous questions in a different fashion: By inverting the Pull
pattern into a Push
pattern.
A Publisher is the asynchronous/push “dual” to the synchronous/pull Iterable
event | Iterable (pull) | Publisher (push) |
---|---|---|
retrieve data |
T next() |
onNext(T) |
discover error |
throws Exception |
onError(Exception) |
complete |
!hasNext() |
onCompleted() |
2. 不仅仅是发送一个值,可以多个值
An Publisher<T>
supports emission sequences of values or even infinite streams, not just the emission of single scalar values (as Futures do). You will very much appreciate this fact once you start to work on streams instead of single values. Project Reactor uses two types in its vocabulary: Mono
and Flux
that are both publishers.
A Mono
can emit 0
to 1
events while a Flux
can emit 0
to N
events.
3. 作为Publisher<T>的消费者,不必关心生产者的实现,不管生产者是同步还是异步,消费者不必跟着修改代码
A Publisher<T>
is not biased toward some particular source of concurrency or asynchronicity and how the underlying code is executed - synchronous or asynchronous, running within a ThreadPool
. As a consumer of a Publisher<T>
, you leave the actual implementation to the supplier, who can change it later on without you having to adapt your code.
4. 有订阅Publisher<T>时,生产者才执行,这是和java.util.concurrent.Future的最大区别
The last key point of a Publisher<T>
is that the underlying processing is not started at the time the Publisher<T>
is obtained, rather its started at the moment an observer subscribes or signals demand to the Publisher<T>
. This is a crucial difference to a java.util.concurrent.Future
, which is started somewhere at the time it is created/obtained. So if no observer ever subscribes to the Publisher<T>
, nothing ever will happen.
出处: