既然 Reactive Stream 和 Java 8 引入的 Stream 都叫作流,它们之间有什么关系呢?有一点关系,Java 8 的 Stream 主要关注在流的过滤,映射,合并,而 Reactive Stream 更进一层,侧重的是流的产生与消费,即流在生产与消费者之间的协调。java
在进行异步消息处理时,Reactive Streams 和 Actor 是两种不一样的编程模式选择。Reactive Streams 规范相比 Actor 更简单,只是说收发消息异步,有流量控制。而 Actor 编程模式涉及到 Actor 容错管理,消息路由,集群,并支持远程消息等。git
还有共同之处是: 它们定义的 API 都很简单,编码时都基本不须要关注线程自己,而实际消息的传递都是背后的线程池。因此线程的配置可延迟到部署阶段来进行优化处理。github
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.app
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 Iterableasync
event | Iterable (pull) | Publisher (push) |
---|---|---|
retrieve datafetch |
T next()优化 |
onNext(T)this |
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.
出处: