0Pricing
Java Academy · Lektion

Wann Parallelität hilft

Faktoren wie Arbeitslast und Datengröße

Wann Parallelität hilft ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Parallelisierung hat ihren Preis

Parallele Verarbeitung verursacht zusätzlichen Aufwand: Daten werden aufgeteilt, Aufgaben verteilt und Ergebnisse zusammengeführt. Sie lohnt sich nur, wenn dieser Aufwand geringer ist als die eingesparte Zeit.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long sum = IntStream.rangeClosed(1, 10_000_000)
            .parallel()
            .asLongStream()
            .sum();
        System.out.println(sum);
    }
}

Faktor 1: Datengröße (N)

Ein großes N verteilt den festen Mehraufwand der Parallelisierung auf mehr Elemente. Als grobe Faustregel gilt: Erst ab einigen Zehntausend Elementen lohnt sich die parallele Verarbeitung.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long count = IntStream.rangeClosed(1, 5_000_000)
            .parallel()
            .filter(n -> n % 7 == 0)
            .count();
        System.out.println(count);
    }
}

Faktor 2: Aufwand pro Element (Q)

Der Aufwand Q für die Verarbeitung jedes Elements ist entscheidend. Aufwendige Berechnungen pro Element profitieren bereits bei einem kleineren N von der Parallelisierung.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long primes = IntStream.rangeClosed(2, 200_000)
            .parallel()
            .filter(Main::isPrime)
            .count();
        System.out.println(primes);
    }

    static boolean isPrime(int n) {
        for (int i = 2; (long) i * i <= n; i++)
            if (n % i == 0) return false;
        return true;
    }
}

Die Intuition hinter N x Q

Betrachten Sie die gesamte nützliche Arbeit als N x Q. Je größer dieses Produkt ist, desto stärker kann die Parallelisierung helfen. Ein sehr kleines N oder ein triviales Q rechtfertigt sie nur selten.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        double sum = IntStream.rangeClosed(1, 1_000_000)
            .parallel()
            .mapToDouble(n -> Math.sqrt(n) * Math.log(n + 1))
            .sum();
        System.out.println(sum);
    }
}

Faktor 3: Aufteilbarkeit

Datenquellen, die sich schnell und gleichmäßig aufteilen lassen, eignen sich gut für die Parallelisierung: Arrays, ArrayList und IntStream.range. LinkedList und iteratorbasierte Quellen lassen sich schlecht aufteilen.

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 1_000_000; i++) list.add(i);
        long even = list.parallelStream().filter(n -> n % 2 == 0).count();
        System.out.println(even);
    }
}

Gute Quelle: Arrays und Bereiche

Primitive Bereiche haben eine bekannte Größe und lassen sich in O(1) aufteilen, wodurch sie ideale parallele Quellen sind.

import java.util.stream.LongStream;

public class Main {
    public static void main(String[] args) {
        long sum = LongStream.rangeClosed(1, 20_000_000)
            .parallel()
            .sum();
        System.out.println(sum);
    }
}

Schlechte Quelle: Iterative Generatoren

Stream.iterate erzeugt Elemente definitionsgemäß sequenziell und kann sie daher erst aufteilen, wenn die Elemente erzeugt wurden. Es ist eine schwache Quelle für parallele Verarbeitung.

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        long count = Stream.iterate(1, n -> n + 1)
            .limit(1_000_000)
            .parallel()
            .filter(n -> n % 2 == 0)
            .count();
        System.out.println(count);
    }
}

Faktor 4: Günstiger Zusammenführungsschritt

Parallelisierung erfordert eine kostengünstige Möglichkeit, Teilergebnisse zu kombinieren. sum und count lassen sich trivial zusammenführen; das Erstellen einer sortierten Liste oder eines baumlastigen Collectors ist dagegen aufwendig.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int max = IntStream.rangeClosed(1, 5_000_000)
            .parallel()
            .map(n -> n % 1000)
            .max()
            .getAsInt();
        System.out.println(max);
    }
}

Nicht für I/O-gebundene Aufgaben verwenden

Parallele Streams sind für CPU-gebundene Aufgaben im Fork-Join-Pool gedacht. Blockierende I/O-Vorgänge belegen den gemeinsam genutzten Pool und beeinträchtigen die gesamte Anwendung. Verwenden Sie stattdessen dedizierte Executor.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long total = IntStream.rangeClosed(1, 1_000_000)
            .parallel()
            .mapToLong(n -> (long) n * n)
            .sum();
        System.out.println(total);
    }
}

Messen statt raten

Die einzige zuverlässige Möglichkeit festzustellen, ob die Parallelisierung hilft, ist ein Benchmark mit realistischen Daten. Die eigene Intuition zur Performance liegt häufig falsch.

import java.util.stream.LongStream;

public class Main {
    public static void main(String[] args) {
        long start = System.nanoTime();
        long sum = LongStream.rangeClosed(1, 50_000_000).parallel().sum();
        long ms = (System.nanoTime() - start) / 1_000_000;
        System.out.println("sum=" + sum + " took ~" + ms + "ms");
    }
}

Eine praktische Checkliste

Bevorzugen Sie die parallele Verarbeitung, wenn alle folgenden Punkte erfüllt sind:

  • Großes N und/oder hoher Aufwand pro Element.
  • Eine aufteilbare Quelle (Array, ArrayList, Bereich).
  • Eine kostengünstige, assoziative Zusammenführung.
  • CPU-gebundene Verarbeitung ohne blockierende I/O-Vorgänge.
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        double avg = IntStream.rangeClosed(1, 10_000_000)
            .parallel()
            .mapToDouble(Math::sqrt)
            .average()
            .getAsDouble();
        System.out.println(avg);
    }
}

Kurze Prüfung

Welches Szenario eignet sich am besten für einen parallelen Stream?

Zusammenfassung

Sie haben gelernt, wann Parallelisierung hilft:

  • Der Nutzen steigt mit N x Q (Datengröße mal Aufwand pro Element).
  • Sie benötigen eine aufteilbare Quelle (Arrays, ArrayList, Bereiche).
  • Sie benötigen eine kostengünstige, assoziative Zusammenführung.
  • Beschränken Sie die Verarbeitung auf die CPU, vermeiden Sie blockierende I/O-Vorgänge und messen Sie immer.

Häufig gestellte Fragen

Ist die Lektion „Wann Parallelität hilft“ kostenlos?

Ja — der vollständige Text von „Wann Parallelität hilft“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Wann Parallelität hilft“?

Faktoren wie Arbeitslast und Datengröße Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Wann Parallelität hilft“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Parallele Streams erstellen
  2. Wann Parallelität hilft
  3. Thread-Sicherheit und Seiteneffekte
  4. Häufige Fallstricke
← Zurück zu Java Academy