RxJava API和Java 9 Flow API的区别

72
每一次Java的迭代都会有新的方式来管理并发任务。在Java 9中,我们有Flow API,它类似于RxJava的Flowable API,但是Java 9只有一组更简单的类和接口。
Java 9有Flow.PublisherFlow.SubscriberFlow.ProcessorFlow.SubscriptionSubmissionPublisher等,仅此而已。而RxJava则有整个Flow API类似的包,例如io.reactivex.flowablesio.reactivex.subscribersio.reactivex.processorsio.reactivex.observersio.reactivex.observables,它们似乎做着类似的事情。那么这两个库之间的主要区别是什么?为什么有人会使用Java 9 Flow库而不是更多样化的RxJava库,反之亦然?
4个回答

69
这两个库有什么主要区别?
Java 9 Flow API不是一个独立的库,而是Java标准版库的一个组件,由4个接口组成,这些接口采用了早在2015年初制定的Reactive Streams规范。理论上,它的包含可以实现JDK特定的用法,例如孵化中的HttpClient、部分计划中的Async Database Connection,以及SubmissionPublisher
RxJava是一个使用ReactiveX风格API设计的Java库,提供了一组丰富的操作符来处理反应式(推送)数据流。通过Flowable和各种XxxProcessor,版本2实现了Reactive Streams API,允许其他兼容库消费Flowable的实例,并将任何Publisher包装成Flowable以消费它们并与其组合丰富的操作符集。
因此,Reactive Streams API是最小的接口规范,而RxJava 2是其中的一种实现,加上RxJava声明了大量附加方法,形成了自己丰富和流畅的API。
RxJava 1的灵感来源包括反应式流规范,但无法利用它(必须保持兼容)。 RxJava 2是一次完全重写和单独的主版本,可以采用并使用反应式流规范(甚至通过Rsc项目在内部扩展),并且比Java 9发布了近一年。此外,决定同时支持Java 6的v1和v2,因此有很多Android运行时。因此,它不能直接利用Java 9直接提供的Flow API,而只能通过bridge。其他基于Reactive Streams的库也需要或提供此桥接程序。
RxJava 3可能针对Java 9 Flow API,但尚未决定,取决于后续Java版本带来的功能(例如值类型),我们可能不会在一年左右内拥有v3。
在那之前,有一个名为Reactive4JavaFlow的原型库,它确实实现了Flow API,并为其提供了一个类似于ReactiveX样式的丰富流畅API。

为什么有人会选择Java 9 Flow库而不是更多样化的RxJava库,反之亦然?

Flow API是一个互操作规范,而不是面向最终用户的API。通常情况下,您不会直接使用它,而是将流传递给各种实现。当讨论JEP 266时,作者们没有发现任何现有库的API足够好,可以与Flow API一起默认使用(与丰富的java.util.Stream不同)。因此,决定目前用户必须依赖第三方实现。
您必须等待现有的响应式库本地支持Flow API,通过它们自己的桥接实现或实现新的库。
只有提供丰富的运算符集才是库实现Flow API的唯一原因。数据源供应商(即,响应式数据库驱动程序、网络库)可以通过Flow API开始实现自己的数据访问者,并依赖于丰富的库来包装它们并为它们提供转换和协调,而不强制所有人实现所有这些运算符。
因此,更好的问题是,现在是否应该开始使用基于Flow API的互操作性,还是坚持使用Reactive Streams?
如果您需要相对较快地获得可靠的解决方案,我建议您暂时坚持使用Reactive Streams生态系统。如果您有充足的时间或想要探索一些东西,那么您可以开始使用Flow API。

50
一开始,有Rx,第一版。它是反应式API的语言无关规范,具有Java、JavaScript和.NET的实现。然后他们对它进行了改进,我们看到了Rx 2。它也有不同语言的实现。在Rx 2时期,Spring团队正在开发Reactor——他们自己的一套反应式API。
然后他们都想:为什么不共同努力,创建一个API来统治所有其他API呢?这就是Reactive Commons的设立方式。一项联合研究工作,旨在构建高度优化的符合反应流操作符标准的API。当前的实现者包括RxJava2和Reactor。
与此同时,JDK开发人员意识到反应性大有可为,并值得纳入Java中。在Java世界中通常会有事实上的标准成为法定标准。还记得Hibernate和JPA,Joda Time和Java8日期/时间API吗?所以JDK开发人员所做的是提取反应式API的核心部分,即最基本的部分,并将其成为一个标准。这就是j.u.c.Flow的诞生方式。
从技术上讲,j.u.c.Flow要简单得多,它只由四个简单接口组成,而其他库则提供了数十个类和数百个操作符。
我希望这回答了“它们之间的区别是什么”的问题。

为什么有人会选择 j.u.c.Flow 而不是 Rx?因为现在它是一个标准!

目前 JDK 只提供了一个实现 j.u.c.Flow 的 API:HTTP/2 API。实际上,它是一个孵化中的 API。但将来我们可能会期望 Reactor、RxJava 2 以及其他库(如反应式数据库驱动程序甚至 FS IO)也支持它。


4
你将几个事件混淆了。Reactive Streams倡议是在RxJava 0.x变得足够稳定后的一个聚集点。Reactive Streams Commons于2016年初问世,其目标正如你所说。 - akarnokd

10

"这两个库之间的主要区别是什么?"

正如你自己指出的,Java 9库更加基础,主要作为响应流的通用API,而不是一种完整的解决方案。

"为什么有人会使用Java 9 Flow库而不是更多样化的RxJava库或反之亦然?"

好吧,人们使用基本库构造而不是库的原因也是同样的 - 减少一个需要管理的依赖项。此外,由于Java 9中的Flow API更为通用,因此受特定实现的限制较少。


5

这两个库之间的主要区别是什么?

在Java9中,JEP 266:更多并发更新引入了FlowAPI,支持以下内容:

  • 嵌套在新类Flow中的支持响应式流发布-订阅框架的接口。

  • Publisher生成由一个或多个Subscriber消耗的项目,每个项目都由一个Subscription管理。

  • 通信依赖于一种简单的流量控制形式(方法Subscription.request,用于通信反向压力),可用于避免可能在“推”式系统中出现的资源管理问题。提供了一个实用程序类SubmissionPublisher,开发人员可以使用它来创建自定义组件。

  • 这些(非常小的)接口对应于由Reactive Streams倡议广泛参与定义的接口,并支持在运行在JVM上的多个异步系统之间的互操作性。

  • 将接口嵌套在类中是一种保守的策略,允许它们在各种短期和长期可能性中使用。没有提供基于网络或I/O的java.util.concurrent分布式消息传递组件的计划,但未来的JDK版本可能会在其他软件包中包括这些API。

为什么有人会选择使用Java 9 Flow库而不是更多元化的RxJava库,反之亦然?

从更广泛的前景来看,这完全是基于意见的,取决于客户端正在开发的应用程序的类型以及其对框架的用途。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接