{"id":3899,"date":"2017-07-01T12:37:09","date_gmt":"2017-07-01T10:37:09","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=3899"},"modified":"2017-07-01T12:37:09","modified_gmt":"2017-07-01T10:37:09","slug":"reaktive-programmierung-und-die-flow-api","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2017\/07\/reaktive-programmierung-und-die-flow-api\/","title":{"rendered":"Reaktive Programmierung und die Flow-API"},"content":{"rendered":"<p>Sollen Produzenten und Konsumenten entkoppelt werden, so gibt es eine Reihe von M\u00f6glichkeiten. Nehmen wir zum Beispiel einen Iterator, der eine einfache API definiert, sodass sich auf immer die gleiche Art und Weise Daten von einem Produzenten abholen lassen. Oder nehmen wir einen Beobachter (Observer\/Listener): ein Produzent verschickt seine Daten an Interessenten. Oder nehmen wir ein Bussystem: Publisher (Sender) und Subscriber (Empf\u00e4nger) senden Datenpakete \u00fcber einen Bus. All diese Design-Pattern sind f\u00fcr bestimmte Anwendungsf\u00e4lle gut, haben jedoch alle eine Schw\u00e4che: es entstehen oft Blockaden und die Gefahr der \u00dcberflutung mit Nachrichten besteht.<\/p>\n<p>Neu in Java 9 sind Schnittstellen eingezogen, die vorher unter http:\/\/www.reactive-streams.org\/ diskutiert und als Defacto-Standard gelten. Ziel ist die Standardisierung von Programmen, die \u201ereaktiv\u201c programmiert sind. Grundidee ist, dass es Publisher und Subscriber gibt, die einen asynchron Datenstrom austauschen aber nicht blockieren und mit \u201eGegendruck\u201c (engl. back pressure) arbeiten. Vergleichen wir das mit dem bekannten Bussystem, dann wird das Problem schnell klar; es kann passieren, dass ein Publisher viel zu schnell Ereignisse produziert, und die Subscriber nicht mitkommen, wo sollen dann die Daten hin? Oder, wenn der Publisher nichts sendet, dann wartet der Subscriber blockierend. Genau diese Probleme m\u00f6chte das reaktive Modell vermeiden, in dem zwischen Publisher und Subscriber liegt ein Vermittler eingeschaltet wird, der \u00fcber Gegendruck steuert, dass der Subscriber Daten anfordert und der Publisher dann so viel sendet, wie nicht-blockierend verarbeitet werden kann. Das realisiert eine Flusskontrolle, sodass wir auch von der Flow-API sprechen.<\/p>\n<p>Die API ist untergebraucht in einer finalen Klasse java.util.concurrent.Flow, die vier statische innere Schnittstellen deklariert:<\/p>\n<pre>@FunctionalInterface\u00a0\u00a0\n\npublic static interface Flow.Publisher&lt;T&gt; {\u00a0\n\n\u00a0\u00a0\u00a0 public void\u00a0\u00a0\u00a0 subscribe(Flow.Subscriber&lt;? super T&gt; subscriber);\u00a0\n\n}\u00a0\u00a0\n\n\u00a0\n\npublic static interface Flow.Subscriber&lt;T&gt; {\u00a0\n\n\u00a0\u00a0\u00a0 public void\u00a0\u00a0\u00a0 onSubscribe(Flow.Subscription subscription);\u00a0\n\n\u00a0\u00a0\u00a0 public void\u00a0\u00a0\u00a0 onNext(T item) ;\u00a0\n\n\u00a0\u00a0\u00a0 public void\u00a0\u00a0\u00a0 onError(Throwable throwable) ;\u00a0\n\n\u00a0\u00a0\u00a0 public void\u00a0\u00a0\u00a0 onComplete() ;\u00a0\n\n}\u00a0\u00a0\n\n\u00a0\n\npublic static interface Flow.Subscription {\u00a0\n\n\u00a0\u00a0\u00a0 public void\u00a0\u00a0\u00a0 request(long n);\u00a0\n\n\u00a0\u00a0\u00a0 public void\u00a0\u00a0\u00a0 cancel() ;\u00a0\n\n}\u00a0\u00a0\n\n\u00a0\n\npublic static interface Flow.Processor&lt;T,R&gt;\u00a0 extends Flow.Subscriber&lt;T&gt;, Flow.Publisher&lt;R&gt; {\u00a0\n\n}<\/pre>\n<p>Es ist gar nicht Aufgabe der Java SE diverse Implementierungen f\u00fcr die Schnittstellen bereitzustellen; es gibt lediglich von Publisher eine Implementierung, java.util.concurrent.SubmissionPublisher&lt;T&gt; . Allgemein sind die Implementierungen aber nicht trivial und daher ist es ratsam, sich mit zum Beispiel RxJava, \u201eReactive Extensions for the JVM\u201c (https:\/\/github.com\/ReactiveX\/RxJava) und Akka Streams (http:\/\/doc.akka.io\/docs\/akka\/2.5.3\/java\/stream\/index.html) zu besch\u00e4ftigen, die Datenstr\u00f6me sehr sch\u00f6n in eine Kette verarbeiten k\u00f6nnen. Der eigentliche Wert der Java SE-Schnittstellen ist, dass es damit zu einer offiziellen API wird und Algorithmen problemlos unter den reaktiven Bibliotheken ausgetauscht werden k\u00f6nnen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sollen Produzenten und Konsumenten entkoppelt werden, so gibt es eine Reihe von M\u00f6glichkeiten. Nehmen wir zum Beispiel einen Iterator, der eine einfache API definiert, sodass sich auf immer die gleiche Art und Weise Daten von einem Produzenten abholen lassen. Oder nehmen wir einen Beobachter (Observer\/Listener): ein Produzent verschickt seine Daten an Interessenten. Oder nehmen wir [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11,85],"tags":[],"class_list":["post-3899","post","type-post","status-publish","format-standard","hentry","category-insel","category-java-9"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3899","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=3899"}],"version-history":[{"count":2,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3899\/revisions"}],"predecessor-version":[{"id":3901,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3899\/revisions\/3901"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=3899"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=3899"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=3899"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}