Modèles avancés de gestion des threads

Optimiser le code en Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Notions de base des pools de threads

Créer des threads coûte cher !

$$

Pools de threads :

  • Réutilisent les threads existants
  • Contrôlent le nombre de threads simultanés
  • Sont gérés via l'interface ExecutorService
Optimiser le code en Java

Créer des pools de threads

// Pool fixe de 4 threads
ExecutorService fixedPool = Executors.newFixedThreadPool(4);


// Pool en cache qui grandit au besoin ExecutorService cachedPool = Executors.newCachedThreadPool();
// Exécuteur à un seul thread ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
Optimiser le code en Java

Soumettre des tâches

ExecutorService executor = Executors.newFixedThreadPool(4);

// Soumettre une tâche sans valeur de retour
executor.execute(() -> System.out.println("Simple task"));

// Soumettre une tâche avec valeur de retour (Callable)
Future<Integer> future = executor.submit(() -> {
    Thread.sleep(1000);
    return 42;
});

// Obtenir le résultat du Future (bloque jusqu'à la fin)
int result = future.get();
Optimiser le code en Java

Arrêter des exécuteurs

// Demander l'arrêt, en laissant finir les tâches en cours
executor.shutdown();


// Attendre la fin (avec délai) boolean terminated = executor.awaitTermination(5, TimeUnit.SECONDS);
// Forcer l'arrêt immédiat, en annulant les tâches en cours executor.shutdownNow();
Optimiser le code en Java

Le CompletableFuture

  • CompletableFuture
  • Fait partie de l'API de concurrence de Java depuis Java 8
  • Approche moderne de la programmation asynchrone
  • Peut être complété manuellement ou via une Function
  • Permet d'enchaîner des opérations avec des callbacks
  • Fonctionne avec ou sans pools de threads explicites
Optimiser le code en Java

Créer des CompletableFuture

// Exécuter de façon asynchrone avec l'exécuteur par défaut
CompletableFuture<Void> runAsync = 
    CompletableFuture.runAsync(() -> performTask());

// Fournir de façon asynchrone avec un exécuteur personnalisé ExecutorService executor = Executors.newCachedThreadPool(); CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> fetchData(), executor);
Optimiser le code en Java

Enchaîner des opérations

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

// Accéder au résultat quand il est prêt
future.thenAccept(result -> System.out.println(result));
Optimiser le code en Java

Passons à la pratique !

Optimiser le code en Java

Preparing Video For Download...