Fortgeschrittene Threading-Muster

Codeoptimierung in Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Grundlagen von Thread-Pools

Threads zu erstellen ist teuer!

$$

Thread-Pools:

  • Vorhandene Threads wiederverwenden
  • Anzahl gleichzeitiger Threads steuern
  • Über das Interface ExecutorService verwaltet
Codeoptimierung in Java

Thread-Pools erstellen

// Fester Thread-Pool mit 4 Threads
ExecutorService fixedPool = Executors.newFixedThreadPool(4);


// Dynamischer Thread-Pool, der bei Bedarf wächst ExecutorService cachedPool = Executors.newCachedThreadPool();
// Single-Thread-Executor ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
Codeoptimierung in Java

Aufgaben übergeben

ExecutorService executor = Executors.newFixedThreadPool(4);

// Aufgabe ohne Rückgabewert übergeben
executor.execute(() -> System.out.println("Simple task"));

// Aufgabe mit Rückgabewert (Callable) übergeben
Future<Integer> future = executor.submit(() -> {
    Thread.sleep(1000);
    return 42;
});

// Ergebnis aus Future holen (blockiert bis fertig)
int result = future.get();
Codeoptimierung in Java

Executors beenden

// Beenden signalisieren, laufende Aufgaben dürfen fertig werden
executor.shutdown();


// Auf Beendigung warten (mit Timeout) boolean terminated = executor.awaitTermination(5, TimeUnit.SECONDS);
// Sofortiges Beenden erzwingen, laufende Aufgaben abbrechen executor.shutdownNow();
Codeoptimierung in Java

Die Completable Future

  • CompletableFuture
  • Teil der Concurrency-API seit Java 8
  • Moderner Ansatz für asynchrone Programmierung
  • Kann manuell oder per Function abgeschlossen werden
  • Ermöglicht verkettete Operationen mit Callbacks
  • Funktioniert mit oder ohne explizite Thread-Pools
Codeoptimierung in Java

Completable Futures erstellen

// Asynchron mit Standard-Executor ausführen
CompletableFuture<Void> runAsync = 
    CompletableFuture.runAsync(() -> performTask());

// Asynchron mit benutzerdefiniertem Executor liefern ExecutorService executor = Executors.newCachedThreadPool(); CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> fetchData(), executor);
Codeoptimierung in Java

Operationen verketten

CompletableFuture<String> future = CompletableFuture
    .supplyAsync(() -> fetchUserData(userId))
    .thenApply(data -> extractUsername(data))
    .exceptionally(ex -> "Unknown user");

// Zugriff auf Ergebnis, sobald bereit
future.thenAccept(result -> System.out.println(result));
Codeoptimierung in Java

Lass uns üben!

Codeoptimierung in Java

Preparing Video For Download...