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 des commonPool 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
    • 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