1. Was ist ein Ausführungs-Thread (thread)
Ein Thread als eigenständige Arbeitseinheit
In Java (und in der Programmierung allgemein) ist ein Ausführungs-Thread eine unabhängige Befehlsfolge, die parallel zu anderen Threads innerhalb eines Programms läuft. Stellen Sie sich eine Fabrik vor: Jede Näherin hat ihren eigenen Arbeitstisch und Auftrag, arbeitet unabhängig – und alles zusammen ergibt das Gesamtergebnis.
Standardmäßig startet ein Java-Programm mit einem Thread – demjenigen, der die Methode main aufruft. Aber nichts hindert uns daran, zusätzliche Threads zu erstellen, damit verschiedene Teile des Programms gleichzeitig ausgeführt werden.
Prozesse und Threads: worin liegt der Unterschied?
- Prozess – das ist eine „schwerfällige“ Ausführungseinheit. Jeder Prozess hat seinen eigenen Speicherbereich, eigene Variablen, eigene Ressourcen. Prozesse sind vollständig voneinander isoliert – wenn einer „abbricht“, sind die anderen nicht betroffen.
- Thread (thread) – das ist eine „leichtgewichtige“ Ausführungseinheit innerhalb eines Prozesses. Alle Threads eines Prozesses teilen sich Speicher und Ressourcen. Das bedeutet, dass sie Daten leicht austauschen können (und leider auch leicht einander stören können).
Analogie:
Ein Prozess ist eine eigene Wohnung: mit eigenen Wänden und Bewohnern.
Threads sind die Bewohner innerhalb einer Wohnung: Jeder hat seine Aufgaben, aber Küche und Bad sind gemeinsam.
Wie sieht das in Java aus?
Wenn Sie ein Programm starten, erstellt die JVM mindestens einen Thread – den Haupt-Thread (main). Sie können jedoch neue Threads erstellen, um Aufgaben parallel auszuführen.
2. Wozu braucht man Multithreading
Reaktionsfähigkeit: Die UI darf nicht „einfrieren“
Angenommen, Sie schreiben ein grafisches Programm – etwa einen Texteditor. Der Benutzer klickt auf die Schaltfläche „Speichern“, und Sie beginnen, eine Datei langwierig auf die Festplatte zu schreiben. Wenn Sie all das im Haupt-Thread tun, „friert“ das Programmfenster ein: Der Benutzer kann nichts anklicken, der Cursor bewegt sich nicht, die Oberfläche reagiert nicht. Speichern Sie die Datei hingegen in einem separaten Thread, bleibt die UI responsiv und der Benutzer kann es sich sogar anders überlegen und das Programm schließen.
Alltagsbeispiel:
Sie öffnen einen Browser und beginnen, eine große Datei herunterzuladen. Würde der Browser keine Threads verwenden, könnten Sie weder einen neuen Tab öffnen noch die Seite scrollen, bis der Download fertig ist!
Parallele Datenverarbeitung
Angenommen, Sie haben eine Liste mit tausend Dateien, die verarbeitet werden müssen (z. B. Hashes neu berechnen oder Text ersetzen). Warum sie nicht parallel verarbeiten? Jeder Thread nimmt sich eine Datei und arbeitet unabhängig – und die gesamte Arbeit ist um ein Vielfaches schneller erledigt.
Beispiel:
Ein Server verarbeitet Anfragen von Hunderten von Clients. Würde der Server das in einem einzigen Thread tun, müssten die anderen Clients ewig warten. Mit Threads wird jede Anfrage unabhängig verarbeitet!
Nutzung von Mehrkern-Prozessoren
Moderne Prozessoren sind nicht ein einzelnes „Gehirn“, sondern ein ganzes Team (Kerne), die parallel arbeiten können. Wenn Ihr Programm nur einen Thread nutzt, langweilen sich die anderen Kerne und spielen Minesweeper. Starten Sie hingegen mehrere Threads, sind alle Kerne beschäftigt und das Programm läuft schneller.
Interessante Tatsache:
Sogar Ihr Telefon hat mehrere Kerne, und Notebooks sowie Server – Dutzende! Sie nicht alle zu nutzen, ist, als würden Sie einen Bus kaufen und allein damit fahren.
3. Beispiele aus der Praxis
| Bereich | Beispiel für Multithreading |
|---|---|
| Dateidownloads | Mehrere Dateien gleichzeitig herunterladen |
| Benutzeroberfläche (UI) | Die Anwendung „friert“ beim Laden/Speichern von Daten nicht ein |
| Server | Parallele Verarbeitung vieler Netzwerk-Anfragen |
| Spiele | Eigene Threads für Physik, Grafik, Musik, KI |
| Messenger | Nachrichten empfangen, Dateien senden, Oberfläche aktualisieren |
| Videoverarbeitung | Frames parallel verarbeiten |
Mini-Analogie:
Der Koch kocht Suppe, während der Ofen parallel einen Kuchen backt und der Saugroboter den Boden reinigt – all das passiert gleichzeitig, und das Abendessen ist schneller fertig!
4. Potenzielle Schwierigkeiten des Multithreadings
Race Condition (Zustandsrennen)
Wenn mehrere Threads gleichzeitig dieselbe Variable ändern, kann das Ergebnis unvorhersehbar sein. Wenn beispielsweise zwei Threads gleichzeitig einen gemeinsamen Zähler erhöhen, kann der Endwert falsch sein. Darüber sprechen wir in einer der nächsten Vorlesungen ausführlicher.
Synchronisierung
Damit sich Threads nicht gegenseitig stören, muss man Wege finden, sich „abzusprechen“ – wer wann Daten ändern darf. Das nennt man Synchronisierung. Dafür gibt es spezielle Schlüsselwörter und Konstruktionen (synchronized, Sperren usw.), auf die wir später eingehen.
Deadlock (gegenseitige Blockierung)
Manchmal „freunden“ sich Threads so an, dass sie einander ewig warten lassen – und das Programm hängt. Das nennt man Deadlock – und es ist einer der tückischsten Fehler in der nebenläufigen Programmierung.
Debugging und Tests
Fehler in nebenläufigen Programmen sind sehr schwer zu fassen: Manchmal funktioniert alles, manchmal nicht. Mitunter zeigt sich der Bug nur auf dem Server oder beim Benutzer, während bei Ihnen am Rechner alles perfekt läuft. Das macht das Testen und Debuggen von Multithreading‑Code zu einer echten Herausforderung für Entwickler.
5. Kurzüberblick: Wie eine Multithreading-Anwendung aussieht
Beispiel ohne Threads:
public class Main {
public static void main(String[] args) {
// Bis 5 zählen
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
// Buchstaben ausgeben
for (char c = 'A'; c <= 'E'; c++) {
System.out.println(c);
}
}
}
Die Ausgabe ist immer gleich:
1
2
3
4
5
A
B
C
D
E
Beispiel mit Threads:
public class Main {
public static void main(String[] args) {
Thread numbers = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println(i);
try {
Thread.sleep(100); // Kurz warten
} catch (InterruptedException e) {
// Ignorieren
}
}
});
Thread letters = new Thread(() -> {
for (char c = 'A'; c <= 'E'; c++) {
System.out.println(c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// Ignorieren
}
}
});
numbers.start();
letters.start();
}
}
Die Ausgabe wird durchmischt sein:
1
A
2
B
3
C
4
D
5
E
oder, wenn die Threads „konkurrieren“, kann die Reihenfolge anders sein. Wichtig ist: Beide Schleifen laufen parallel!
6. Nützliche Feinheiten
Visuelles Schema: wie Threads zusammenarbeiten
+-------------------+ +-------------------+
| Haupt-Thread | | Zweiter Thread |
+-------------------+ +-------------------+
| 1 | 2 | 3 | 4 | 5 | | A | B | C | D | E |
+-------------------+ +-------------------+
| |
| Beide arbeiten |
| gleichzeitig |
+-------------------------+
Wo Java „unter der Haube“ Threads verwendet
- Garbage Collection (Garbage Collector) – ein eigener Thread räumt nicht mehr verwendete Objekte auf.
- Ein-/Ausgabe (I/O) – Datei lesen/schreiben, Netzwerkverbindungen.
- Server und Web-Anwendungen – jede Client-Anfrage wird in einem eigenen Thread verarbeitet.
- Timer, Task-Scheduler – Aufgaben nach Zeitplan ausführen.
7. Typische Anfängerfehler
Fehler Nr. 1: Die Erwartung, dass Threads ein Programm immer beschleunigen.
Tatsächlich kann Multithreading, wenn Sie eine Single-Core‑Maschine haben oder die Arbeit falsch organisiert ist, die Ausführung sogar verlangsamen – wegen „Verwirrung“ und Overhead beim Umschalten zwischen Threads.
Fehler Nr. 2: Probleme der Synchronisierung ignorieren.
Viele sind überzeugt: „Ich starte doch nur zwei Threads – was kann da schon schiefgehen?“ Wenn jedoch beide Threads eine Variable ändern, kann das Ergebnis völlig unerwartet sein.
Fehler Nr. 3: Threads für alles und jedes einsetzen.
Sie sollten keinen separaten Thread für jeden „Pups“ starten. Threads sind eine Ressource, und eine übermäßige Anzahl kann zu Verlangsamungen und sogar zum Absturz des Programms führen.
Fehler Nr. 4: Fehlende Fehlerbehandlung.
Threads können Ausnahmen auslösen (z. B. bei Datei‑ oder Netzwerkarbeit). Wenn Sie diese Fehler nicht behandeln, kann das Programm abstürzen oder „hängen bleiben“.
GO TO FULL VERSION