pp.08.03-CommonPool
commonPool
- Projekt:
pp.08.03-CommonPool
- Bearbeitungszeit: 10 Minuten
- Musterlösung: 10 Minuten
- Kompatibilität: mindestens Java SE 10
Der commonPool
- Das ist eine Instanz der Klasse
ForkJoinPool
(kommt gegen Ende des Semesters dran). ForkJoinPool
folgt dem Singleton Entwurfsmuster: Es gibt höchstens eine Instanz.commonPool
wird automatisch erzeugt, wenn eines der Nebenläufigkeits-Frameworks, die dies unterstützen, verwendet wird (u.a.CompletableFuture
, Parallel Streams, Fork-Join).- Der
commonPool
hat u.a. Eigenschaften eines Fixed Threadpool:- eingebaute Regel für Anzahl der Threads: \(\mbox{Anzahl Cores}-1\)
- kann mit
-D
-Parameter beim Start der JVM geändert werden:
java -Djava.util.concurrent.ForkJoinPool.common.parallelism=20 Main
- Dieser Threadpool unterstützt zusätzlich auch “Work Stealing” (später im Semester).
- \(\to\) sehr leistungsfähig und ohne Aufwand zu benutzen (
ExecutorService
-Interface)ForkJoinPool.commonPool()
erzeugt ggf.commonPool
und liefert Referenz auf ihn zurück
Quellcode von pp.CommonPoolTest
In dieser Laboraufgabe soll nicht programmiert werden. Deshalb gibt es auch ausnahmsweise kein Eclipse-Projekt mit einer Musterlösung. Das Programm in der Klasse CommonPoolTest
ist dazu da, die Funktionsweise des commonPool
genauer zu untersuchen.
package pp;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.LinkedList;
public class CommonPoolTest {
private static void sleep() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private static void output(int task, String event) {
var thread = Thread.currentThread().getName();
System.out.printf("Task-%02d %s by %s\n", task, event, thread);
}
public static void main(String... args)
throws InterruptedException, ExecutionException {
var cores = Runtime.getRuntime().availableProcessors();
var commonPool = ForkJoinPool.commonPool();
System.out.println("# Cores: " + cores);
System.out.println("# Threads: " + commonPool.getParallelism());
var futures = new LinkedList<Future<?>>();
for (var task : new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }) {
futures.add(commonPool.submit(() -> {
output(task, "started");
sleep();
output(task, "finished");
return task;
}));
output(task, "submitted");
}
for (var future : futures) {
output((int) future.get(), "delivered");
}
commonPool.shutdown();
}
}
Aufgaben
- Überprüfen Sie, ob die Regel für Anzahl der Threads im
commonPool
auf Ihrem System umgesetzt ist (\(\mbox{Parallelität} = \mbox{Anzahl Cores}-1\)) anhand der Konsolenausgabe, indem Sie das Programm laufen lassen. - Analysieren Sie den Quelltext und die Konsolenausgabe in Hinblick auf die Charakteristik des Threadpools.
- Ändern Sie die Größe des
commonPool
(Parallelität = Anzahl der Threads), indem Sie mit dem JVM-Kommandozeilenparameter
-Djava.util.concurrent.ForkJoinPool.common.parallelism=X
(setzt die Parallelilität descommonPool
auf \(X\)) setzen. Dazu gibt es folgende Möglichkeiten- Nehmen Sie entweder das vorbereitete Shell-Skript im Wurzelverzeichnis des Projekts oder…
- Verwenden Sie Maven manuell:
- Gehen Sie in das Verzeichnis des Projekts
cd .../pp.08.03-CommonPool
- Starten Sie Maven mit dem
exec:java
-Ziel und übergeben Sie den JVM-Kommandozeilenparameter mit-D
(X
=1, 2, 20 etc.)
mvn clean compile exec:java -Djava.util.concurrent.ForkJoinPool.common.parallelism=X
- Gehen Sie in das Verzeichnis des Projekts
- alternativ: Starten Sie die JVM manuell:
- Gehen Sie in das Verzeichnis
target/classes
cd .../pp.08.03-CommonPool/target/classes
- Starten Sie
CommonPoolTest.main
in der JVM mit (X
= 1, 2, 20 etc.)
java -Djava.util.concurrent.ForkJoinPool.common.parallelism=X pp.CommonPoolTest
- Gehen Sie in das Verzeichnis