© DrHitch/Shutterstock.com
Shortcuts
Java 7

2 Das Fork-Join-Framework im Einsatz

Das Fork-Join-Framework ist eine der Neuerungen in Java 7. Im ersten Kapitel haben wir uns die internen Mechanismen dieses Frameworks angesehen. Diesmal wollen wir es in einem konkreten Beispiel einsetzen und uns danach anschauen, wie das Framework in zukünftigen JDK-Abstraktionen genutzt werden wird.

Shortcut Autorenteam


2.1 Beispiel: Suche des größten Elements in einem ArrayWir wollen nun an einem Beispiel die Benutzung des Fork-Join-Frameworks erläutern. Mithilfe des Fork-Join-Frameworks wollen wir in einem int-Array das größte Element finden. Im ersten Schritt geht es darum, das Problem der Suche auf eine Fork-Join-Task-Struktur zurückzuführen. Hier bietet sich eine Lösung an, die auf der binären Suche (Binary Search) basiert. In unserem Fall bedeutet es, dass wir in der ersten Stufe das Array halbieren und mit je einer Subtask in jedem Teil-Array das größte Element suchen. Dieses Halbieren des Array-Intervalls, auf dem die Subtask die eigentliche Suche durchführen soll, kann man rekursiv weiter fortsetzen. So ergibt sich die Fork-Phase. Wenn das Intervall klein genug ist, suchen wir dann sequenziell das größte Element in diesem kleinen Intervall. Im Sinne der Bezeichnung aus Abbildung 1.1 ist dies die Berechnung. In der anschließenden Join-Phase wird jede Task die Ergebnisse ihrer beiden Subtasks hernehmen, vergleichen und das größere von beiden Ergebnissen als eigenes Ergebnis weiterreichen. Die Join-Phase setzt sich fort, bis man zum Ergebnis der Ausgangstask kommt.Nun zur eigentlichen Implementierung. Für rekursive Probleme wie unseres wird man nicht die ForkJoinTask direkt nutzen. Vielmehr gibt es im Fork-Join-Framwork bereits die Abstraktionen RecursiveAction und RecursiveTask. Beides sind Subklassen der ForkJoinTask. Die RecursiveTask steht für Tasks zur Verfügung, die ein Ergebnis produzieren, die RecursiveAction für Tasks, die kein Ergebnis haben. Das heißt, die RecursiveAction wartet zwar beim Join auf ihre Subtasks, die Subtasks produzieren aber kein Ergebnis – anders als bei der RecursiveTask, wo die Subtasks Ergebnisse zurückliefern.In unserem Problem hat die Task eigentlich ein Ergebnis, nämlichen den maximalen Wert in dem Intervall, das ihr zugeteilt worden ist. Also müssten wir die RecursiveTask für unsere Implementierung hernehmen. Die RecursiveTask ist eine generische Klasse, deren Typparameter der Typ des Ergebnisses der Task ist. Das heißt, in unserem Fall wäre dies der Typ Integer, und wir müssten eine RecursiveTask verwenden. Da wir die Suche auf einem int-Array durchführen wollen, wird für das Ergebnis immer eine Umwandlung von int in Integer (Boxing) notwendig. Aus Performancegründen wollen wir aber gerne auf dieses zusätzliche Boxing verzichten. Deshalb verwenden wir in unserer Implementierung die RecursiveAction und kümmern uns um d...

Shortcuts
Java 7

2 Das Fork-Join-Framework im Einsatz

Das Fork-Join-Framework ist eine der Neuerungen in Java 7. Im ersten Kapitel haben wir uns die internen Mechanismen dieses Frameworks angesehen. Diesmal wollen wir es in einem konkreten Beispiel einsetzen und uns danach anschauen, wie das Framework in zukünftigen JDK-Abstraktionen genutzt werden wird.

Shortcut Autorenteam


2.1 Beispiel: Suche des größten Elements in einem ArrayWir wollen nun an einem Beispiel die Benutzung des Fork-Join-Frameworks erläutern. Mithilfe des Fork-Join-Frameworks wollen wir in einem int-Array das größte Element finden. Im ersten Schritt geht es darum, das Problem der Suche auf eine Fork-Join-Task-Struktur zurückzuführen. Hier bietet sich eine Lösung an, die auf der binären Suche (Binary Search) basiert. In unserem Fall bedeutet es, dass wir in der ersten Stufe das Array halbieren und mit je einer Subtask in jedem Teil-Array das größte Element suchen. Dieses Halbieren des Array-Intervalls, auf dem die Subtask die eigentliche Suche durchführen soll, kann man rekursiv weiter fortsetzen. So ergibt sich die Fork-Phase. Wenn das Intervall klein genug ist, suchen wir dann sequenziell das größte Element in diesem kleinen Intervall. Im Sinne der Bezeichnung aus Abbildung 1.1 ist dies die Berechnung. In der anschließenden Join-Phase wird jede Task die Ergebnisse ihrer beiden Subtasks hernehmen, vergleichen und das größere von beiden Ergebnissen als eigenes Ergebnis weiterreichen. Die Join-Phase setzt sich fort, bis man zum Ergebnis der Ausgangstask kommt.Nun zur eigentlichen Implementierung. Für rekursive Probleme wie unseres wird man nicht die ForkJoinTask direkt nutzen. Vielmehr gibt es im Fork-Join-Framwork bereits die Abstraktionen RecursiveAction und RecursiveTask. Beides sind Subklassen der ForkJoinTask. Die RecursiveTask steht für Tasks zur Verfügung, die ein Ergebnis produzieren, die RecursiveAction für Tasks, die kein Ergebnis haben. Das heißt, die RecursiveAction wartet zwar beim Join auf ihre Subtasks, die Subtasks produzieren aber kein Ergebnis – anders als bei der RecursiveTask, wo die Subtasks Ergebnisse zurückliefern.In unserem Problem hat die Task eigentlich ein Ergebnis, nämlichen den maximalen Wert in dem Intervall, das ihr zugeteilt worden ist. Also müssten wir die RecursiveTask für unsere Implementierung hernehmen. Die RecursiveTask ist eine generische Klasse, deren Typparameter der Typ des Ergebnisses der Task ist. Das heißt, in unserem Fall wäre dies der Typ Integer, und wir müssten eine RecursiveTask verwenden. Da wir die Suche auf einem int-Array durchführen wollen, wird für das Ergebnis immer eine Umwandlung von int in Integer (Boxing) notwendig. Aus Performancegründen wollen wir aber gerne auf dieses zusätzliche Boxing verzichten. Deshalb verwenden wir in unserer Implementierung die RecursiveAction und kümmern uns um d...

Neugierig geworden?


    
Loading...

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang