0Pricing
Java Academy · Leçon

Future et gestion des erreurs

Utilisez Future.get avec des délais d’attente, gérez ExecutionException et annulez les tâches en cours.

Future et gestion des erreurs est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

Qu’est-ce qu’un résultat différé ?

Un Future<V> représente le résultat en attente d’un calcul asynchrone. Il fournit des méthodes pour vérifier la fin du calcul, attendre le résultat et gérer les erreurs.

import java.util.concurrent.*;

ExecutorService pool = Executors.newFixedThreadPool(2);
Future<Integer> future = pool.submit(() -> {
    Thread.sleep(1000);
    return 42;
});

System.out.println("Is done? " + future.isDone()); // false
Integer result = future.get(); // blocks
System.out.println("Result: " + result); // 42
pool.shutdown();

<code>future.get()</code> avec délai d’attente

Préférez toujours la variante avec délai d’attente afin d’éviter un blocage indéfini :

try {
    Integer result = future.get(5, TimeUnit.SECONDS);
    System.out.println(result);
} catch (TimeoutException e) {
    System.out.println("Timed out");
    future.cancel(true); // interrupt the task
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
} catch (ExecutionException e) {
    System.out.println("Task threw: " + e.getCause());
}

ExecutionException

Si la tâche a levé une exception, future.get() l’enveloppe dans une ExecutionException. Extrayez l’exception d’origine avec getCause() :

Future<String> failing = pool.submit(() -> {
    throw new IllegalArgumentException("bad input");
});

try {
    failing.get();
} catch (ExecutionException e) {
    Throwable cause = e.getCause();
    System.out.println(cause.getClass().getSimpleName()); // IllegalArgumentException
    System.out.println(cause.getMessage()); // bad input
}

Annuler un résultat différé

cancel(mayInterruptIfRunning) tente d’annuler la tâche. La méthode renvoie vrai en cas de réussite. Si mayInterruptIfRunning vaut vrai, une interruption est envoyée au fil d’exécution en cours.

Future<String> f = pool.submit(() -> {
    try {
        Thread.sleep(10_000); // long task
        return "done";
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        return "interrupted";
    }
});

boolean cancelled = f.cancel(true); // send interrupt
System.out.println("Cancelled: " + cancelled); // true
System.out.println("Is cancelled: " + f.isCancelled()); // true

isCancelled contre isDone

isDone() renvoie vrai si la tâche s’est terminée normalement, a levé une exception ou a été annulée. isCancelled() renvoie vrai uniquement si elle a été annulée.

// After cancel:
System.out.println(f.isDone());       // true
System.out.println(f.isCancelled()); // true

// After normal completion:
Future<Integer> done = pool.submit(() -> 5);
done.get(); // wait
System.out.println(done.isDone());       // true
System.out.println(done.isCancelled()); // false

CompletionService pour les résultats disponibles en premier

ExecutorCompletionService encapsule un ensemble de fils et fournit une méthode take() pour récupérer le prochain résultat différé terminé, dans l’ordre d’achèvement et non dans l’ordre de soumission :

ExecutorCompletionService<Integer> cs =
    new ExecutorCompletionService<>(pool);

for (int i = 0; i < 5; i++) {
    final int delay = 5 - i; // submit fastest last
    cs.submit(() -> { Thread.sleep(delay * 100); return delay; });
}

for (int i = 0; i < 5; i++) {
    Future<Integer> f = cs.take(); // next completed
    System.out.println(f.get());
}

Gérer plusieurs résultats différés en toute sécurité

Lorsque vous récupérez les résultats de nombreux résultats différés, parcourez-les et gérez les exceptions séparément pour chacun :

List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    final int id = i;
    futures.add(pool.submit(() ->
        id % 2 == 0 ? "ok_" + id : (() -> { throw new RuntimeException("fail_"+id); }).get()
    ));
}

for (Future<String> f : futures) {
    try {
        System.out.println(f.get());
    } catch (ExecutionException e) {
        System.out.println("Error: " + e.getCause().getMessage());
    }
}

Future.get() après l’arrêt de l’ensemble

Une soumission effectuée après shutdown() lève RejectedExecutionException. En revanche, les résultats différés soumis BEFORE l’arrêt peuvent encore être récupérés après celui-ci :

ExecutorService pool2 = Executors.newFixedThreadPool(2);
Future<Integer> f = pool2.submit(() -> 99);
pool2.shutdown(); // no new tasks

// Still valid — task was submitted before shutdown:
System.out.println(f.get()); // 99

try {
    pool2.submit(() -> 0); // throws!
} catch (RejectedExecutionException e) {
    System.out.println("Pool shut down");
}

FutureTask : résultat différé manuel

FutureTask<V> implémente à la fois une tâche exécutable et un Future<V> — utile lorsque vous avez besoin d’un résultat différé sans ExecutorService :

FutureTask<String> task = new FutureTask<>(() -> "computed");
new Thread(task).start(); // run in any thread
System.out.println(task.get()); // computed

Modèle de nouvelle tentative avec un résultat différé

Implémentez une logique simple de nouvelle tentative autour de future.get() :

Future<String> future = pool.submit(() -> {
    if (Math.random() < 0.7) throw new RuntimeException("transient error");
    return "success";
});

for (int attempt = 0; attempt < 3; attempt++) {
    try {
        System.out.println(future.get());
        break;
    } catch (ExecutionException e) {
        System.out.println("Attempt " + (attempt+1) + " failed");
        if (attempt == 2) throw e;
        future = pool.submit(() -> "retry"); // resubmit
    }
}

Limitations des résultats différés

Le résultat différé de java.util.concurrent présente plusieurs limitations :

  • Aucun rappel : vous devez bloquer avec get()
  • Impossible d’enchaîner les transformations
  • Impossible de combiner plusieurs résultats différés

Utilisez CompletableFuture (dans le cours suivant) pour composer des opérations réactives et sans blocage.

Vérification rapide

Une tâche lève une exception. Quelle exception est levée lorsque vous appelez future.get() ?

Récapitulatif : résultats différés et gestion des erreurs

Points essentiels :

  • future.get() bloque ; utilisez toujours la variante avec délai d’attente
  • ExecutionException enveloppe les exceptions de la tâche ; extrayez-les avec getCause()
  • cancel(true) envoie une interruption ; utilisez isDone/isCancelled pour connaître l’état
  • ExecutorCompletionService.take() récupère les résultats différés dans l’ordre d’achèvement
  • FutureTask implémente à la fois une tâche exécutable et un résultat différé

Questions Fréquemment Posées

La leçon « Future et gestion des erreurs » est-elle gratuite ?

Oui — le texte complet de « Future et gestion des erreurs » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Future et gestion des erreurs » ?

Utilisez Future.get avec des délais d’attente, gérez ExecutionException et annulez les tâches en cours. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Future et gestion des erreurs » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. ExecutorService et types de pools de threads
  2. Soumettre des tâches : Runnable et Callable
  3. Future et gestion des erreurs
  4. ScheduledExecutorService pour les tâches récurrentes
← Retour à Java Academy