Asynchrone Programmierung in Java: Vollständiger Praxisleitfaden

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

Einführung in die asynchrone Programmierung in Java



Moderne Anwendungen erfordern hohe Leistung und Reaktionsfähigkeit. Benutzer sind nicht bereit zu warten, während die Anwendung eine Datenbankabfrage verarbeitet oder einen Netzwerkaufruf durchführt. Hier kommt die asynchrone Programmierung in Java ins Spiel – ein Ansatz, der den Hauptausführungs-Thread nicht blockiert, während auf den Abschluss langwieriger Operationen gewartet wird.



Im Gegensatz zur traditionellen Multithreading-Programmierung, bei der Sie Threads explizit verwalten, bietet die asynchrone Programmierung Abstraktionen auf höherer Ebene. Anstatt manuell neue Threads zu erstellen, verwenden Sie CompletableFuture, ExecutorService und andere Werkzeuge der Java Concurrency API.



In diesem Artikel behandeln wir die wichtigsten Konzepte der asynchronen Programmierung in Java mit praktischen Beispielen. Sie erfahren, wie Sie asynchrone Aufgaben verarbeiten, zu Ketten verknüpfen und effizient mit Multithreading arbeiten.



Grundlegende Werkzeuge der asynchronen Programmierung in Java



1. CompletableFuture – Grundlage der Asynchronität



CompletableFuture ist eine Klasse, die in Java 8 eingeführt wurde und eine leistungsstarke API für asynchrone Programmierung bereitstellt. Sie ermöglicht das Erstellen asynchroner Aufgaben, deren Verknüpfung, Fehlerbehandlung und Transformation von Ergebnissen.



Betrachten wir ein einfaches Beispiel zum Erstellen und Ausführen einer asynchronen Aufgabe:



import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;

public class AsyncExample { public static void main(String[] args) throws ExecutionException, InterruptedException { // Asynchrone Aufgabe erstellen CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); // Simulation einer langwierigen Operation } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return "Ergebnis der asynchronen Operation"; });

// Abschluss-Handler hinzufügen future.thenAccept(result -> System.out.println("Ergebnis erhalten: " + result));

// Haupt-Thread arbeitet weiter System.out.println("Haupt-Thread setzt die Ausführung fort");

// Auf Abschluss warten (nur zur Demonstration) future.get(); }}


Beachten Sie, dass supplyAsync() standardmäßig ForkJoinPool.commonPool() verwendet. Dies ist ein Thread-Pool, der für parallele Aufgaben optimiert ist.



2. ExecutorService – Verwaltung des Thread-Pools



Für eine feinere Kontrolle über die Ausführung asynchroner Aufgaben verwenden Sie ExecutorService. Damit können Sie die Anzahl der Threads, ihr Verhalten und die Strategie zur Aufgabenverarbeitung festlegen.



import java.util.concurrent.*;

public class ExecutorServiceExample { public static void main(String[] args) { // Pool mit 4 Threads erstellen ExecutorService executor = Executors.newFixedThreadPool(4);

// CompletableFuture mit benutzerdefiniertem Executor erstellen CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return 42; }, executor);

// Ergebnisverarbeitung future.thenAccept(result -> { System.out.println("Ergebnis: " + result); executor.shutdown(); // Wichtig! Pool schließen });

System.out.println("Haupt-Thread wird nicht blockiert"); }}


Wichtig: Schließen Sie ExecutorService immer mit shutdown() oder shutdownNow(), um Ressourcenlecks zu vermeiden.



3. Verkettung

Blogs

Buchempfehlungen