Philipp Bayer BridgingIT GmbH

Multi-Threading ist in Java seit jeher ein schwieriges und fehleranfälliges Thema.

Tilmann Kuhn BridgingIT GmbH

Die Entwickler von Scala haben sich dieser Problematik angenommen und ein API entwickelt, mit dem asynchrone Aufgaben in einer nichtblockierenden Art gesteuert werden können.

Während Java gerade erst in Version 8 ein relativ leichtgewichtiges API zur asynchronen Ausführung voneinander abhängiger Tasks erhalten hat, gibt es solche Möglichkeiten woanders schon seit geraumer Zeit. Scala ermöglicht es, mithilfe von Futures und Promises asynchrone Operationen zu erstellen, zu verknüpfen und die Ergebnisse weiterzuverarbeiten. Durch erweiterte Möglichkeiten im Bereich Exception Handling ist das API auch tauglich für den Alltagseinsatz jenseits der kleinen vorgestellten Artikelbeispiele.
Multi-Threading ist in Java seit jeher ein schwieriges und fehleranfälliges Thema. Neben der inhärenten Komplexität des Themengebiets gab es bislang kein API, das Entwicklern ein angenehmes Abstraktionsniveau bot. Erschwerend kommt hinzu, dass die Korrektheit von Multi-Threading-Code nicht einfach in Unit-Tests zu überprüfen ist. So ist es nicht verwunderlich, dass bislang oft versucht wurde, das Handling von mehreren Threads zu vermeiden. Und obwohl Oracle das Java-Concurrent-API immer wieder erweitert und weiterentwickelt hat, bieten erst die neuesten Ergänzungen in Java 8 mit CompletableFuture die notwendige Simplizität, um wirklich einfach die Abläufe von mehreren asynchronen Threads programmatisch zu steuern. Die länger vorhandenen API-Features wie Futures und ExecutorServices, ForkJoinPools oder gar Locks und Semaphores bieten zwar alle benötigten Grundlagen und könnten auch direkt verwendet werden, haben aber in den meisten Fällen ein zu niedriges Abstraktionsniveau für eine einfache Anwendung. Das niedrige Abstraktionsniveau macht es Anfängern in dem Thema leicht, Fehler zu machen, und führt auch schnell zu viel Boilerplate-Code, der dem Clean-Code-Gedanken zuwiderläuft. Gerade im Vergleich mit anderen Sprachen muss sich Java den Vorwurf gefallen lassen, dieses Thema bisher etwas stiefmütterlich behandelt zu haben. So ist es in JavaScript-Applikationen spätestens seit der Standardisierung von Promises ein Leichtes, asynchronen Code zu entwickeln. Dennoch ist es für moderne Java-Applikationen sinnvoll, sich eingehender mit diesem Thema zu befassen, da moderne Prozessorarchitekturen nur unter Verwendung von Multi-Threading-Code optimal genutzt werden können.

Multi-Threading in Scala

Die Entwickler von Scala haben sich dieser Problematik angenommen und ein API entwickelt, mit dem asynchrone Aufgaben in einer nichtblockierenden Art gesteuert werden können. Die Basis dafür bildet das Fork/Join-API, das mit Java 7 eingeführt wurde. Es ist ideal, um eine Reihe von kurzen, nichtblockierenden Jobs zu starten und zu verwalten und wird z. B. auch vom Java-8-Streams-API verwendet. Dabei wird eine Reihe von Worker-Threads erstellt, die die ihnen zugewiesenen Jobs abarbeiten. Sobald ein Worker-Thread keine eigenen Jobs mehr hat, versucht er, sich Jobs von anderen Worker-Threads zu nehmen. Das Scala-Concurrent-API erstellt standardmäßig einen Worker-Thread pro CPU-Kern. Diese Konfiguration lässt sich aber nach Belieben anpassen. Im Folgenden wollen wir die beiden Kernelemente des Scala-Concurrent-API vorstellen: Future und Promise. Konzeptuell kann man sich beide Objekte als Container für Werte vorstellen. Diese Werte existieren zwar noch nicht, wenn man die Container erstellt, werden aber zu einem späteren Zeitpunkt bekannt sein.

Den vollständigen Artikel lesen Sie in der Ausgabe:

Java Magazin 6.17 - "Continuous Delivery"

Alle Infos zum Heft
579796481Multi-Threading in Scala
X
- Gib Deinen Standort ein -
- or -