2016-03-28 5 views
14

Ich habe gerade angefangen habe einige Gleichzeitigkeit Funktionen von Java 8. Eine Sache zu erforschen verwirrt mich ein bisschen diese beiden statischen Methoden ist:CompletableFuture supplyAsync

CompletableFuture<Void> runAsync(Runnable runnable) 
CompletableFuture<U> supplyAsync(Supplier<U> supplier) 

Sie jemand wissen, warum sie wählen Schnittstelle Lieferant zu benutzen? Ist es nicht natürlicher, Callable zu verwenden, was die Analogie zu Runnable ist, die einen Wert zurückgibt? Liegt das daran, dass der Lieferant keine Ausnahme auslöst, die nicht bearbeitet werden kann?

+0

Weil sie von C# einfach anders sein mußte, die 'Aktion allgemein genannt wird <>' und ' Func <> 'Schnittstellen, die den gleichen Job machen, aber ohne den Programmierer zu verwirren. Und so wuchsen sie funktionale Schnittstellen für Methoden mit den gleichen Signaturen, aber unterschiedlichen Namen. Sie dachten wahrscheinlich, dass es dem Programmierer helfen würde, indem sie ihm ein mentales Modell zur Verfügung stellten, aber es ist nicht so: Es ist nur eine kleine PITA. – davidbak

Antwort

7

Kurze Antwort

Nein, es ist nicht mehr natürliche Callable zu verwenden, anstatt Supplier in CompletableFuture.supplyAsync. Das Argument dreht sich fast ausschließlich um Semantik, also ist es in Ordnung, wenn Sie danach noch nicht überzeugt sind.

Lange Antwort

Die Callable und Supplier funktionalen Schnittstellen/SAM-Typen praktisch in der Funktion äquivalent sind (verzeihen Sie das Wortspiel), aber ihre Herkunft und Verwendungszweck unterscheiden.

Callable wurde als Teil des java.util.concurrent Pakets erstellt. Dieses Paket kam vor den großen Änderungen rund um Lambda-Ausdrücke in Java 8 und konzentrierte sich ursprünglich auf eine Reihe von Tools, mit denen Sie gleichzeitig Code schreiben konnten, ohne viel vom klassischen Modell des praktischen Multithreading abzuweichen.

Der Hauptzweck von Callable bestand darin, eine Aktion zu abstrahieren, die in einem anderen Thread ausgeführt werden kann und die ein Ergebnis zurückgibt. Von Callable ‚s Javadoc:

Die Callable Schnittstelle ist ähnlich Runnable, dass beide sind konzipiert für die Klassen, deren Instanzen möglicherweise ausgeführt durch ein anderer Thread.

Supplier wurde als Teil des java.util.function Paket erstellt. Dieses Paket war ein integraler Bestandteil der oben genannten Änderungen in Java 8. Es bietet allgemeine funktionale Typen, auf die Lambda-Ausdrücke und Methodenreferenzen abzielen können.

Ein solcher Typ ist eine Funktion ohne Parameter, die ein Ergebnis liefert (d. H. Eine Funktion, die einen Typ oder eine Supplier-Funktion liefert).

Warum also Supplier und nicht Callable?

CompletableFuture ist Teil Ergänzungen das java.util.concurrent Paket, das 8 durch die vorgenannten Änderungen in Java inspiriert wurden und dass damit der Entwickler seinen Code in einer funktionalen, implizit parallelizable Weise zu konstruieren, statt explizit Umgang mit Parallelität innerhalb dieser Gruppe.

Ihre Methode benötigt einen Weg, um ein Ergebnis eines bestimmten Typs zu liefern und ist mehr an diesem Ergebnis interessiert, und nicht an der Aktion, die unternommen wird, um dieses Ergebnis zu erreichen. Es kümmert sich auch nicht unbedingt um außergewöhnliche Fertigstellung (siehe auch die Was ist mit dem ... Absatz unten).

Dennoch, wenn Runnable für No-Parameter verwendet wird, soll kein Ergebnis funktionale Schnittstelle, nicht Callable für No-Parameter verwendet wird, funktionale Schnittstelle Single-Ergebnis?

Nicht unbedingt.

Eine Abstraktion für eine Funktion, die keinen Parameter hat und kein Ergebnis zurückgibt (und daher vollständig durch Nebeneffekte für den äußeren Kontext funktioniert), wurde in java.util.function nicht berücksichtigt. Dies bedeutet, dass (etwas störend) Runnable überall dort eingesetzt wird, wo eine solche funktionale Schnittstelle benötigt wird.

Was ist mit der geprüften Exception, die von Callable.call() geworfen werden kann?

Es ist ein kleines Zeichen des beabsichtigten semantischen Unterschieds zwischen Callable und Supplier.

Eine Callable ist eine Aktion, die in einem anderen Thread ausgeführt werden kann und die es ermöglicht, ihre Nebenwirkungen als Ergebnis ihrer Ausführung zu überprüfen. Wenn alles gut geht, erhalten Sie ein Ergebnis eines bestimmten Typs, aber da beim Ausführen einiger Aktionen (insbesondere im Multithread-Kontext) Ausnahmesituationen auftreten können, sollten Sie auch solche Ausnahmesituationen definieren und behandeln.

Eine Supplier Auf der anderen Seite ist eine Funktion, auf die Sie für die Bereitstellung von Objekten eines bestimmten Typs angewiesen sind. Außergewöhnliche Situationen sollten nicht unbedingt Ihre Verantwortung als direkter Verbraucher der Supplier sein. Dies ist so, weil:

  1. ... funktionale Schnittstellen sind für die Definition einer bestimmten Stufe in einem mehrstufigen Verfahren häufig verwendet für die Erstellung oder mutiert Daten und Handhabung Exception s kann eine separate Bühne sein, falls Sie kümmern
  2. ... explizit die ausdrucks~~POS=TRUNC von funktionalen Schnittstellen, Lambda-Ausdrücke und Verfahren deutlich reduziert s Handhabung Exception verweist
+0

Ich denke, deine Argumente, dass der Hauptunterschied auf der semantischen Seite liegt, nicht auf der praktischen Seite, ist richtig. Die semantische Verwendung einer Methode namens _CallAsync_ impliziert nicht, dass ein Ergebnis zurückgegeben wird. –

+0

IMO die ganze Idee, Funktionsschnittstellen mit verschiedenen Methoden für die gleiche Funktionalität (z. B. Call() 'vs' Get() ') getrennt benannt wurde schlecht durchdacht und führt zu vielen Ärgernissen. Zwei sind insbesondere: versuchen, sich daran zu erinnern, welche Methode Sie aufrufen müssen und dann nicht in der Lage sind, einen Lieferanten zu schicken, der eine Methode benötigt, die Callable benötigt usw. Die von Ihnen beschriebene "Semantik" ist alles in Worten und nichts mit irgendetwas zu tun haben, was der Compiler erzwingen würde und in den Java-Dokumenten schlecht beschrieben oder gar nicht beschrieben wird. C# hat es besser gemacht. – davidbak

Verwandte Themen