Nebenläufigkeit und Multithreading in Java: Ein vollständiger Leitfaden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Concurrency und Multithreading in Java: Von der Theorie zur Praxis



In der modernen Softwarewelt hängt die Anwendungsleistung direkt von der Fähigkeit ab, Prozessorressourcen effizient zu nutzen. Concurrency und Multithreading in Java sind Schlüsselkonzepte, mit denen Sie mehrere Aufgaben gleichzeitig ausführen, die Datenverarbeitung beschleunigen und reaktionsfähige Benutzeroberflächen erstellen können. In diesem Artikel werden wir die grundlegenden Mechanismen des Multithreading in Java aufschlüsseln, lernen, wie man Threads erstellt und verwaltet, und uns auch mit Best Practices zur Vermeidung häufiger Fehler befassen.



Was ist ein Thread und wie erstellt man einen in Java?



Ein Thread ist ein leichtgewichtiger Prozess, der innerhalb einer einzelnen Anwendung ausgeführt wird. Jeder Thread hat seinen eigenen Aufrufstapel und kann unabhängig von anderen Threads arbeiten. In Java gibt es zwei Hauptmethoden, um einen Thread zu erstellen.



Methode 1: Vererben von der Thread-Klasse

public class MyThread extends Thread {    @Override    public void run() {        System.out.println("Thread " + getName() + " started!");    }

public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // Starting the thread }}


Methode 2: Implementieren des Runnable-Interfaces

public class MyRunnable implements Runnable {    @Override    public void run() {        System.out.println("Thread is running via Runnable");    }

public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); }}


Es wird empfohlen, die zweite Methode zu verwenden, da sie keine Vererbung erfordert und die gleichzeitige Implementierung mehrerer Schnittstellen ermöglicht.



Thread-Synchronisation: Vermeidung von Wettlaufsituationen



Wenn mehrere Threads gleichzeitig auf gemeinsame Daten zugreifen, tritt eine Wettlaufsituation auf. Um dies zu vermeiden, bietet Java Synchronisationsmechanismen.



Das Schlüsselwort synchronized

Blockiert den Zugriff auf eine Methode oder einen Codeblock für andere Threads, bis der aktuelle Thread die Ausführung beendet hat:

public class Counter {    private int count = 0;

public synchronized void increment() { count++; }

public synchronized int getCount() { return count; }}


Sperren mit Lock

Ein flexiblerer Mechanismus als synchronized. Ermöglicht das Festlegen von Zeitüberschreitungen und den Versuch, eine Sperre zu erlangen, ohne zu blockieren:

import java.util.concurrent.locks.ReentrantLock;

public class SafeCounter { private final ReentrantLock lock = new ReentrantLock(); private int count = 0;

public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); // Always release the lock } }}


Thread-Pool und ExecutorService



Das Erstellen eines neuen Threads für jede Aufgabe ist ein teurer Vorgang. Um Threads effizient zu verwalten, verwenden Sie ExecutorService aus dem Paket java.util.concurrent.



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

public class ThreadPoolExample { public static void main(String[] args) { // Create a pool of 4 threads ExecutorService executor = Executors.newFixedThreadPool(4);

for (int i = 0; i < 10; i++) { final int taskId = i; executor.submit(() -> { System.out.println("Task " + taskId + " is executing in " + Thread.currentThread().getName()); }); }

executor.shutdown(); // Shut down the pool after all tasks are completed }}


Haupttypen von Pools:

  • newFixedThreadPool(n) — feste Anzahl von Threads

Blogs

Buchempfehlungen