Java - Thread Pools (Deutsch)

Hallo在那里, zukünftige Java-Entwickler! Heute werden wir in die faszinierende Welt der Thread-Pools eintauchen. Keine Sorge, wenn du neu bei der Programmierung bist; ich werde dich Schritt für Schritt durch dieses Konzept führen, genau wie ich es für unzählige Studenten in meinen Jahren des Unterrichtens getan habe. Also, nimm dir einen Tasse Kaffee (oder Tee, wenn das deine Präferenz ist) und lasst uns beginnen!

Java - Thread Pools

Was sind Thread Pools?

Stelle dir vor, du betreibst ein geschäftiges Restaurant. Jedes Mal, wenn ein neuer Kunde hereinkommt, könntest du einen neuen Kellner einstellen, um ihn zu bedienen. Das wäre jedoch chaotisch und teuer! Stattdessen hast du eine feste Anzahl von Kellnern, die mehrere Kunden bedienen. Das ist im Grunde genommen, was ein Thread-Pool in der Java-Programmierung macht.

Ein Thread-Pool ist eine Gruppe von vorab instanzierten, wiederverwendbaren Threads, die verfügbar sind, um Aufgaben auszuführen. Anstatt für jede Aufgabe einen neuen Thread zu erstellen, was ressourcenintensiv sein kann, verwenden wir einen Pool existierender Threads, um diese Aufgaben auszuführen.

Warum Thread Pools in Java verwenden?

Du fragst dich vielleicht, "Warum sollte ich mir die Mühe mit Thread-Pools machen? Können wir nicht einfach neue Threads erstellen, wenn wir sie benötigen?" Nun, lassen Sie mich das mit einer kleinen Geschichte aus meiner Lehrerfahrung erklären.

Einmal hatte ich einen Studenten, der versuchte, für jede Aufgabe in seiner Anwendung einen neuen Thread zu erstellen. Sein Programm funktionierte gut für kleine Eingaben, aber als er versuchte, eine große Datenmenge zu verarbeiten, krachte sein Computer fast! Das war, als ich ihn mit Thread-Pools vertraut gemacht habe.

Hier sind einige Hauptgründe, warum man Thread Pools verwenden sollte:

  1. Bessere Leistung: Das Erstellen und Zerstören von Threads ist teuer. Thread-Pools wiederverwenden Threads, was Overhead spart.
  2. Ressourcenverwaltung: Du kannst die maximale Anzahl von Threads kontrollieren, die gleichzeitig laufen können.
  3. Verbesserte Reaktionsfähigkeit: Aufgaben können sofort von einem bereits laufenden Thread ausgeführt werden.

Thread Pools in Java erstellen

Java bietet mehrere Möglichkeiten, Thread-Pools über die Executors-Klasse zu erstellen. Sehen wir uns drei gängige Methoden an:

1. Erstellen eines Thread Pools mit der Methode newFixedThreadPool()

Diese Methode erstellt einen Thread-Pool mit einer festen Anzahl von Threads. Hier ist ein Beispiel:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);

for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}

executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Alle Threads abgeschlossen");
}
}

class WorkerThread implements Runnable {
private String message;

public WorkerThread(String s) {
this.message = s;
}

public void run() {
System.out.println(Thread.currentThread().getName() + " (Start) Nachricht = " + message);
processMessage();
System.out.println(Thread.currentThread().getName() + " (Ende)");
}

private void processMessage() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

In diesem Beispiel erstellen wir einen festen Thread-Pool mit 5 Threads. Wir reichen dann 10 Aufgaben an diesen Pool weiter. Der Pool verwendet seine 5 Threads, um diese 10 Aufgaben auszuführen und wiederverwendet Threads, wenn sie verfügbar sind.

2. Erstellen eines Thread Pools mit der Methode newCachedThreadPool()

Diese Methode erstellt einen Thread-Pool, der neue Threads erstellt, wenn nötig, aber vorhandene Threads wiederverwendet. Sehen wir uns an, wie das funktioniert:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();

for (int i = 0; i < 100; i++) {
executor.execute(new Task());
}

executor.shutdown();
}
}

class Task implements Runnable {
public void run() {
System.out.println("Thread Name: " + Thread.currentThread().getName());
}
}

In diesem Beispiel erstellen wir einen zwischengespeicherten Thread-Pool und reichen 100 Aufgaben an ihn weiter. Der Pool erstellt neue Threads, wenn nötig, und verwendet sie, wenn möglich.

3. Erstellen eines Thread Pools mit der Methode newScheduledThreadPool()

Diese Methode erstellt einen Thread-Pool, der Befehle zur Ausführung planen kann, nach einer bestimmten Verzögerung oder periodisch. Hier ist ein Beispiel:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

Runnable task = () -> System.out.println("Ausführung der Aufgabe bei " + System.nanoTime());

executor.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);
}
}

In diesem Beispiel erstellen wir einen geplanten Thread-Pool mit einem Thread. Wir planen dann eine Aufgabe, die alle 2 Sekunden ausgeführt wird.

Methoden in ExecutorService

Hier ist eine Tabelle der wichtigen Methoden in der ExecutorService-Schnittstelle:

Methode Beschreibung
execute(Runnable) Führt den angegebenen Befehl zu einem späteren Zeitpunkt aus
submit(Callable) Reicht einen Aufgabe mit Rückgabewert zur Ausführung ein und gibt ein Future zurück
shutdown() Initiert einen geordneten Shutdown, bei dem vorher eingereichte Aufgaben ausgeführt werden, aber keine neuen Aufgaben akzeptiert werden
shutdownNow() Versucht, alle aktiven Ausführungen zu stoppen und die Verarbeitung von wartenden Aufgaben anzuhalten
isShutdown() Gibt true zurück, wenn dieser Executor heruntergefahren wurde
isTerminated() Gibt true zurück, wenn alle Aufgaben nach dem Herunterfahren abgeschlossen sind

Fazit

Und so ist es, Leute! Wir haben die Welt der Java Thread Pools erkundet, von der Verständnis, warum sie nützlich sind, bis hin zur Erstellung und Nutzung in verschiedenen Weisen. Denke daran, genau wie in unserer Restaurant-Analogie helfen Thread Pools uns, unsere Ressourcen effizient zu verwalten.

In meinen Jahren des Unterrichtens habe ich Studenten gesehen, die von den grundlegenden Konzepten der Threadings zu komplexen, effizienten multi-threaded Anwendungen aufgebaut haben. Mit Übung und Geduld wirst du es auch schaffen!

Führe weiterhin dein Java-Abenteuer fort, erkunde und experimentiere. Thread Pools sind nur ein Werkzeug in dem umfangreichen Toolkit, das Java für die konkurrierende Programmierung bietet. Frohes Coden und möge deine Threads immer effizient gepoolt sein!

Credits: Image by storyset