RxJava API和Java 9 Flow API之间的区别


67

在最近几个主要版本的Java的每次迭代中,似乎都有一致的新方法来管理并发任务。

在Java中9,我们有流API这类似于可流动API RxJava,但与Java 9有一个更简单的一组类和接口。

Java 9

Flow.PublisherFlow.SubscriberFlow.ProcessorFlow.Subscription,和SubmissionPublisher,这就是它。

RxJava的

拥有全流API状类,即io.reactivex.flowablesio.reactivex.subscribersio.reactivex.processorsio.reactivex.observers,和io.reactivex.observables这似乎做同样的事情。

这两个库之间的主要区别是什么?为什么有人会使用Java 9 Flow库,而不是使用更多种类的RxJava库,反之亦然?

Answers:


63

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

Java 9 Flow API不是一个独立的库,而是Java Standard Edition库的一个组件,由从2015年初建立的Reactive Streams规范采用的4个接口组成。从理论上讲,它的包含可以实现JDK中的特定用法,例如孵化中的HttpClient,当然也可能是计划中的Async Database Connection SubmissionPublisher

RxJava是Java库,它使用ReactiveX样式的API设计来为响应(推送)数据流提供丰富的运算符集。版本2Flowable以及其他版本XxxProcessor,实现了Reactive Streams API,该API允许Flowable其他兼容库使用实例,然后又可以将其中的任何实例包装Publisher为,Flowable以使用这些实例,并与它们一起构成一组丰富的运算符。

因此,Reactive Streams API是最小的接口规范,而RxJava 2是它的一个实现,再加上RxJava声明了大量其他方法来形成自己丰富而流畅的API。

RxJava 1在其他来源中启发了Reactive Streams规范,但无法利用它(必须保持兼容)。RxJava 2是完整的重写和单独的主要版本,可以包含和使用Reactive Streams规范(由于Rsc项目,甚至可以在内部对其进行扩展),并且已经比Java 9早一年发布了。决定v1和v2都继续支持Java 6,因此支持许多Android运行时。因此,它不能直接利用Java 9现在提供的Flow API,而只能通过桥接器。其他基于Reactive Streams的库也需要和/或提供这种桥接。

RxJava 3可能针对Java 9 Flow API,但这尚未确定,并且取决于后续Java版本带来的功能(即值类型),我们可能会在一年左右的时间内没有v3。

直到那时,还有一个名为Reactive4JavaFlow的原型库,它确实实现了Flow API,并在其上提供了ReactiveX样式丰富的fluent API。

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

Flow API是互操作规范,而不是最终用户API。通常,您不会直接使用它,而是将流传递给它的各种实现。在讨论JEP 266时,作者没有发现任何现有库的API足以使Flow API具有默认值(不同于rich java.util.Stream)。因此,决定用户现在必须依靠第三方实现。

您必须等待现有的反应式库通过它们自己的桥实现或要实现的新库来原生支持Flow API。

通过Flow API提供丰富的运算符集只是库将实现它的原因。数据源供应商(例如,反应性数据库驱动程序,网络库)可以开始通过Flow API实现其自己的数据访问器,并依靠丰富的库来包装它们,并为其提供转换和协调,而不必强迫所有人实施所有这些运算符。

因此,一个更好的问题是,您现在应该立即使用基于Flow API的互操作还是坚持使用反应式流?

如果您很快需要工作且可靠的解决方案,建议您暂时坚持使用Reactive Streams生态系统。如果您有足够的时间或想要探索事物,则可以开始使用Flow API。


46

最初有Rx版本1。它是反应性API的语言不可知规范,具有Java,JavaScript,.NET的实现。然后他们改进了它,我们看到了Rx 2。它还具有针对不同语言的实现。在Rx 2时,Spring团队正在研究Reactor,这是他们自己的一组反应式API。

然后他们都想:为什么不共同努力,创建一个API来统治所有人。这就是反应式公共空间的建立方式。共同研究工作,以建立高度优化的反应流顺应性运营商。当前的实现者包括RxJava2和Reactor。

同时,JDK开发人员意识到,反应性功能非常好,值得在Java中使用。在Java世界中,事实上的标准已成为法律上的惯例。是否要记住Hibernate和JPA,Joda Time和Java 8 Date / Time API?因此,JDK开发人员所做的就是提取反应性API的最核心部分(最基本的部分)并将其成为标准。那就是这样j.u.c.Flow诞生的。

从技术上讲,j.u.c.Flow它要简单得多,它仅包含四个简单的接口,而其他库则提供了数十个类和数百个运算符。

我希望这能回答“它们之间有什么区别”的问题。

为什么有人会选择j.u.c.FlowRx?好吧,因为现在这是一个标准!

当前,JDK仅提供以下一种实现j.u.c.FlowHTTP / 2 API。它实际上是一个孵化API。但是将来,我们可能期望它得到Reactor,RxJava 2以及其他库(例如反应式数据库驱动程序甚至FS IO)的支持。


4
您已经混淆了一些事件。在RxJava 0.x变得足够稳定之后,Reactive Streams计划就成为了聚集点。Reactive Streams Commons于2016年初问世,目标是您正确陈述。
akarnokd

9

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

就像您自己指出的那样,Java 9库更加基础,并且基本上用作反应性流的通用API,而不是完善的解决方案。

“为什么有人会使用Java 9 Flow库,而不是使用种类繁多的RxJava库,反之亦然?”

嗯,出于同样的原因,人们在库上使用基本的库结构-减少了对管理的依赖。同样,由于Java 9中的Flow API更通用,因此它不受特定实现方式的约束。


4

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

JEP 266:这在大多数情况下都是有用的注释(但太长了,无法放入),JEP 266:负责Flow在Java9中引入API的更多并发更新在其说明中对此做了说明(强调我的意思)-

  • 支持Reactive Streams发布-订阅框架的接口,嵌套在新的Flow类中。

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

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

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

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

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

放眼更广阔的前景,这完全基于诸如客户端正在开发的应用程序类型及其框架的使用等因素得出的意见。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.