Il semble qu'à chaque itération de Java pour les dernières versions majeures, il existe constamment de nouvelles façons de gérer les tâches simultanées.

Dans Java 9, nous avons le API Flow qui ressemble à l 'API Flowable de RxJava mais avec Java 9 a un ensemble beaucoup plus simple de classes et d'interfaces.

Java 9

A un Flow.Publisher, Flow.Subscriber, Flow.Processor, Flow.Subscription et SubmissionPublisher, et c'est à peu près tout.

RxJava

Contient des packages entiers de Flow API, c'est-à-dire io.reactivex.flowables, io.reactivex.subscribers, io.reactivex.processors, io.reactivex.observers et io.reactivex.observables qui semblent faire quelque chose similaire.

Quelles sont les principales différences entre ces deux bibliothèques? Pourquoi quelqu'un utiliserait-il la bibliothèque Java 9 Flow sur la bibliothèque RxJava beaucoup plus diversifiée ou vice versa?

65
Dovmo 17 nov. 2017 à 19:10

4 réponses

Meilleure réponse

Quelles sont les principales différences entre ces deux bibliothèques?

L'API Java 9 Flow n'est pas une bibliothèque autonome mais un composant de la bibliothèque Java Standard Edition et se compose de 4 interfaces adoptées à partir de Spécification Reactive Streams établie au début de 2015. En théorie, son inclusion peut permettre des utilisations spécifiques au JDK, telles que l'incubation HttpClient, peut-être la connexion de base de données Async prévue en partie, et bien sûr { {X0}}.

RxJava est une bibliothèque Java qui utilise la conception d'API de style ReactiveX pour fournir un riche ensemble d'opérateurs sur des flux de données réactifs (push). La version 2, via Flowable et divers XxxProcessor s, implémente l'API Reactive Streams qui permet aux instances de Flowable d'être consommées par d'autres bibliothèques compatibles et à son tour on peut encapsuler n'importe quel {{X3} } dans un Flowable pour les consommer et composer le riche ensemble d'opérateurs avec eux.

Ainsi, l'API Reactive Streams est la spécification d'interface minimale et RxJava 2 en est une implémentation , et RxJava déclare un grand ensemble de méthodes supplémentaires pour former une API riche et fluide de sa propre.

RxJava 1 a inspiré, entre autres sources, la spécification Reactive Streams mais n'a pas pu capitaliser dessus (devait rester compatible). RxJava 2, étant une réécriture complète et une version principale séparée, pourrait adopter et utiliser la spécification Reactive Streams (et même l'étendre en interne, grâce à projet Rsc) et a été publié presque un an avant Java 9. De plus, il a été décidé que la v1 et la v2 continueraient à prendre en charge Java 6 et donc de nombreux environnements d'exécution Android. Par conséquent, il ne pouvait pas capitaliser directement sur l'API Flow fournie maintenant par Java 9 directement, mais uniquement via un pont. Un tel pont est également requis par et / ou fourni dans d'autres bibliothèques basées sur Reactive Streams.

RxJava 3 peut cibler l'API Java 9 Flow, mais cela n'a pas encore été décidé et en fonction des fonctionnalités apportées par les versions Java suivantes (c'est-à-dire des types de valeur), nous pourrions ne pas avoir la v3 d'ici un an environ.

Jusque-là, il existe une bibliothèque prototype appelée Reactive4JavaFlow qui implémente l'API Flow et offre un style ReactiveX API riche et fluide dessus.

Pourquoi quelqu'un utiliserait-il la bibliothèque Java 9 Flow sur la bibliothèque RxJava beaucoup plus diversifiée ou vice versa?

L'API Flow est une spécification d'interopérabilité et non une API d'utilisateur final. Normalement, vous ne l'utiliseriez pas directement mais pour en transmettre des flux à diverses implémentations. Lorsque JEP 266 a été discuté, les auteurs n'ont trouvé aucune API de bibliothèque existante suffisamment bonne pour avoir quelque chose par défaut avec l'API Flow (contrairement à la riche java.util.Stream). Par conséquent, il a été décidé que les utilisateurs devront pour l'instant s'appuyer sur des implémentations tierces.

Vous devez attendre que les bibliothèques réactives existantes prennent en charge nativement l'API Flow, via leur propre implémentation de pont ou de nouvelles bibliothèques à implémenter.

Fournir un riche ensemble d'opérateurs via l'API Flow est la seule raison pour laquelle une bibliothèque l'implémenterait. Les fournisseurs de sources de données (c'est-à-dire les pilotes de base de données réactifs, les bibliothèques réseau) peuvent commencer à implémenter leurs propres accesseurs de données via l'API Flow et s'appuyer sur les bibliothèques riches pour les encapsuler et fournir la transformation et la coordination pour eux sans forcer tout le monde à implémenter toutes sortes de ces opérateurs. .

Par conséquent, une meilleure question est la suivante: devriez-vous commencer à utiliser l'interopérabilité basée sur l'API Flow maintenant ou vous en tenir à Reactive Streams?

Si vous avez besoin de solutions fiables et fonctionnelles assez rapidement, je vous suggère de vous en tenir à l'écosystème Reactive Streams pour le moment. Si vous avez suffisamment de temps ou si vous souhaitez explorer des choses, vous pouvez commencer à utiliser l'API Flow.

59
akarnokd 17 nov. 2017 à 21:52

Quelles sont les principales différences entre ces deux bibliothèques?

Cela est principalement vrai en tant que commentaire informatif (mais trop long pour tenir dans), le JEP 266: More Concurrency Updates responsable de l'introduction de l'API Flow dans Java9 indique ceci dans sa description (c'est moi qui souligne) -

  • Interfaces prenant en charge les Reactive Streams publier-souscrire framework , imbriqué dans la nouvelle classe Flow .

  • Publisher produit des articles consommé par un ou plusieurs Subscriber, chacun étant géré par un Subscription.

  • La communication repose sur une forme simple de contrôle de flux (méthode Subscription.request, pour communiquer la contre-pression) qui peut être utilisé pour éviter les problèmes de gestion des ressources qui pourraient systèmes basés sur "push". Une classe utilitaire SubmissionPublisher est fournie que les développeurs peuvent utiliser pour créer des composants personnalisés.

  • <↓ Ces (très small) correspondent à celles définies avec une large participation (issu de l'initiative Reactive Streams) et soutenir l'interopérabilité sur un certain nombre de systèmes asynchrones fonctionnant sur des JVM.

  • L'imbrication des interfaces dans une classe est une politique conservatrice permettant leur utilisation dans diverses possibilités à court et à long terme . Là ne prévoit pas de fournir des services basés sur le réseau ou les E / S java.util.concurrent composants pour la messagerie distribuée, mais il est possible que le futur JDK les versions incluront ces API dans d’autres packages .

Pourquoi quelqu'un utiliserait-il la bibliothèque Java 9 Flow sur la bibliothèque RxJava beaucoup plus diversifiée ou vice versa?

En regardant une perspective plus large, il s'agit entièrement d'une opinion basée sur des facteurs tels que le type d'application qu'un client développe et ses usages du framework.

4
Naman 17 nov. 2017 à 17:37

Au début, il y avait Rx, la première version. C'était une spécification indépendante du langage des API réactives qui a des implémentations pour Java, JavaScript, .NET. Ensuite, ils l'ont amélioré et nous avons vu Rx 2. Il a également des implémentations pour différentes langues. Au moment de Rx 2, l'équipe Spring travaillait sur Reactor - leur propre ensemble d'API réactives.

Et puis ils ont tous pensé: pourquoi ne pas faire un effort commun et créer une API pour les gouverner tous. C'est ainsi que Reactive Commons a été mis en place. Un effort de recherche conjoint pour construire des opérateurs conformes aux flux réactifs hautement optimisés. Les implémenteurs actuels incluent RxJava2 et Reactor.

Dans le même temps, les développeurs JDK ont réalisé que les éléments réactifs sont excellents et valent la peine d'être inclus dans Java. Comme il est habituel dans le monde Java, le standard de facto devient de jure. Remeber Hibernate et JPA, Joda Time et API Java 8 Date / Time? Donc, ce que les développeurs JDK ont fait, c'est d'extraire le cœur même des API réactives, la partie la plus élémentaire, et d'en faire un standard. C'est ainsi que j.u.c.Flow est né.

Techniquement, j.u.c.Flow est beaucoup plus simple, il se compose uniquement de quatre interfaces simples, tandis que d'autres bibliothèques fournissent des dizaines de classes et des centaines d'opérateurs.

J'espère que cela répond à la question "quelle est la différence entre eux".

Pourquoi quelqu'un choisirait-il j.u.c.Flow plutôt que Rx? Eh bien, parce que maintenant c'est un standard!

Actuellement, JDK est livré avec une seule implémentation de j.u.c.Flow: API HTTP / 2. C'est en fait une API en incubation. Mais à l'avenir, nous pourrions nous attendre à ce qu'il soit supporté par Reactor, RxJava 2 ainsi que par d'autres bibliothèques, comme les pilotes DB réactifs ou même FS IO.

46
madhead 7 déc. 2017 à 09:54

"Quelles sont les principales différences entre ces deux bibliothèques?"

Comme vous l'avez noté vous-même, la bibliothèque Java 9 est beaucoup plus basique et sert essentiellement d'API générale pour les flux réactifs au lieu d'une solution à part entière.

"Pourquoi quelqu'un utiliserait-il la bibliothèque Java 9 Flow sur la bibliothèque RxJava beaucoup plus diversifiée ou vice versa?"

Eh bien, pour la même raison, les gens utilisent des constructions de bibliothèque de base plutôt que des bibliothèques - une dépendance de moins à gérer. De plus, du fait que l'API Flow dans Java 9 est plus générale, elle est moins contrainte par l'implémentation spécifique.

9
Piotr Wilkin 17 nov. 2017 à 16:21
47354837