Commit 1a71db1a authored by Blanke, Daniela's avatar Blanke, Daniela
Browse files

Update concurrency-streams.html

parent 6ebb4ddc
Pipeline #8036 passed with stage
in 1 minute and 13 seconds
......@@ -112,8 +112,8 @@ Diese Teilaufgaben können in der Fork-Phase rekursiv in noch kleinere Teilaufga
<label>Grundlegende Klassen des Fork-Join-Framework</label>
<ul>
<li><b>Tasks</b>: <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ForkJoinTask.html"><code>ForkJoinTasks</code></a> sind abgeschlossene Arbeitseinheiten/Teilprobleme, die nicht auf andere Tasks warten müssen. Sie sich nicht an einen bestimmten Thread zur Ausführung gebunden und implementieren das <code>Future</code>-Interface, versprechen also i.d.R. ein Ergebnis bestimmten Typs (= <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/RecursiveTask.html"><code>RecursiveTask</code></a>). Tasks ohne Ergebnis heißen <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/RecursiveAction.html"><code>RecursiveAction</code></a>.</li>
<li><b>Threads</b>: In einem <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ForkJoinPool.html"><code>ForkJoinPool</code></a> werden spezielle Threads, nämlich <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ForkJoinWorkerThread.html"><code>ForkJoinWorkerThreads</code></a> verwaltet, die <code>ForkJoinTasks</code> ausführen. Ein <code>ForkJoinPool</code> unterscheidet sich anderen <code>ExecutorServices</code> durch sogenanntes <i>Work Stealing</i>, d.h. alle Threads im Pool versuchen aktiv, in den Pool gesendete Tasks zu ergreifen und auszuführen. Dies ermöglicht eine effiziente Verarbeitung, insbesondere wenn die Tasks ihrerseits neue Tasks erzeugen – dadurch dass ein <code>ForkJoinTask</code> typischerweise eine Teilaufgabe rekursiv in kleinere Teilaufgaben zerlegt und diese wieder an den Pool sendet.</li>
<li><b>Tasks</b>: <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ForkJoinTask.html"><code>ForkJoinTasks</code></a> sind abgeschlossene Arbeitseinheiten/Teilprobleme, die nicht auf andere Tasks warten müssen. Sie sind nicht an einen bestimmten Thread zur Ausführung gebunden und implementieren das <code>Future</code>-Interface, versprechen also i.d.R. ein Ergebnis bestimmten Typs (= <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/RecursiveTask.html"><code>RecursiveTask</code></a>). Tasks ohne Ergebnis heißen <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/RecursiveAction.html"><code>RecursiveAction</code></a>.</li>
<li><b>Threads</b>: In einem <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ForkJoinPool.html"><code>ForkJoinPool</code></a> werden spezielle Threads, nämlich <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ForkJoinWorkerThread.html"><code>ForkJoinWorkerThreads</code></a> verwaltet, die <code>ForkJoinTasks</code> ausführen. Ein <code>ForkJoinPool</code> unterscheidet sich von anderen <code>ExecutorServices</code> durch sogenanntes <i>Work Stealing</i>, d.h. alle Threads im Pool versuchen aktiv, in den Pool gesendete Tasks zu ergreifen und auszuführen. Dies ermöglicht eine effiziente Verarbeitung, insbesondere wenn die Tasks ihrerseits neue Tasks erzeugen – dadurch dass ein <code>ForkJoinTask</code> typischerweise eine Teilaufgabe rekursiv in kleinere Teilaufgaben zerlegt und diese wieder an den Pool sendet.</li>
</ul>
<p>Das Fork-Join-Framework kann auch manuell ohne parallele Streams eingesetzt werden. Das folgende Code-Beispiel demonstriert wie die Berechnung einer bestimmmten Fibonacchi-Zahl über eine <code>RecursiveTask</code> parallelisiert werden kann. Das Beispiel ist aus der Dokumentation der <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/RecursiveTask.html"><code>RecursiveTask</code></a>-Klasse übernommen. Die Implementierung ist nicht effizient, da die gebildeten Teilaufgaben zu klein sind. Stattdessen ist – wie bei allen Fork-Join-Anwendungen – eine sinnvolle, minimale Granularität zu wählen, ab der eine Aufgabe sequentiell gelöst wird, anstatt sie zu unterteilen. Die Methode <code>fork</code> in Zeile 9 erzeugt eine Teilaufgabe, die nebenläufig über den <code>ForkJoinPool</code> abgearbeitet wird. Über die Methode <code>join</code> in Zeile 11 wird im aufrufenden Thread auf das Ergebnis dieser Teilaufgabe gewartet.</p>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment