Java Academy · Leçon

Gestion des erreurs et annulation

Propagez proprement les échecs

Leçon 4 sur 413 étapes

Gestion des erreurs et annulation est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 4 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.

Échecs dans un arbre de tâches

Lorsque des sous-tâches s'exécutent en parallèle, des erreurs peuvent survenir dans n'importe quelle branche. La concurrence structurée fournit une manière rigoureuse de propager ces échecs jusqu'à la tâche parente.

Cette leçon couvre les exceptions, l'annulation, l'interruption et les délais d'attente.

Où apparaissent les exceptions

Une sous-tâche qui lève une exception ne fait pas immédiatement planter votre programme. L'exception est capturée dans la référence Subtask. L'endroit où elle apparaît dépend de la stratégie :

  • ShutdownOnFailure : lors de l'appel à throwIfFailed()
  • ShutdownOnSuccess : lors de l'appel à result() si aucune sous-tâche n'a réussi

Propagation avec throwIfFailed

Ici, une sous-tâche échoue. throwIfFailed() la relance, encapsulée dans une ExecutionException, que nous intercepterons dans main.

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            scope.fork(() -> "ok");
            scope.fork(() -> { throw new RuntimeException("boom"); });
            scope.join();
            scope.throwIfFailed();
            System.out.println("never reached");
        } catch (ExecutionException e) {
            System.out.println("Caught cause: " + e.getCause().getMessage());
        }
    }
}

Transformer en exception personnalisée

throwIfFailed accepte une fonction qui encapsule la cause dans votre propre type d'exception, afin de préserver la clarté de votre API.

import java.util.concurrent.StructuredTaskScope;

class DataAccessException extends Exception {
    DataAccessException(Throwable cause) { super(cause); }
}

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            scope.fork(() -> { throw new RuntimeException("db down"); });
            scope.join();
            scope.throwIfFailed(DataAccessException::new);
        } catch (DataAccessException e) {
            System.out.println("Wrapped: " + e.getCause().getMessage());
        }
    }
}

Annulation automatique

Lorsqu'une sous-tâche échoue avec ShutdownOnFailure, le scope annule les tâches sœurs en interrompant leurs fils d'exécution. Vous n'avez vous-même aucun code d'annulation à écrire.

Cela évite le travail inutile et les tâches qui restent en suspens.

L'interruption est le mécanisme

L'annulation fonctionne en interrompant le fil d'exécution virtuel de la sous-tâche. Un code coopératif doit :

  • Laisser les appels bloquants lever InterruptedException
  • Vérifier périodiquement Thread.currentThread().isInterrupted() dans les longues boucles

Réagir à l'interruption

Cette tâche vérifie l'indicateur d'interruption dans une boucle afin de pouvoir s'arrêter plus tôt lorsque le scope s'arrête.

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t = Thread.ofVirtual().start(() -> {
            long count = 0;
            while (!Thread.currentThread().isInterrupted()) {
                count++;
                if (count == 1_000_000) break;
            }
            System.out.println("Stopped after " + count + " iterations");
        });
        t.join();
    }
}

Échéances avec joinUntil

Pour limiter la durée totale, utilisez joinUntil(Instant). Si l'échéance est dépassée avant la fin de toutes les sous-tâches, l'appel lève TimeoutException et le scope arrête les tâches restantes.

Structure type avec délai d'attente

Voici à quoi ressemble généralement une répartition protégée par un délai d'attente. L'échéance s'applique à l'ensemble du groupe, et non à chaque sous-tâche individuellement.

import java.time.*;
import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            scope.fork(() -> "fast");
            scope.joinUntil(Instant.now().plus(Duration.ofSeconds(2)));
            scope.throwIfFailed();
            System.out.println("Completed within deadline");
        } catch (TimeoutException e) {
            System.out.println("Deadline exceeded");
        } catch (ExecutionException e) {
            System.out.println("A subtask failed");
        }
    }
}

Vérifiez toujours après join

La règle est la suivante : après join() ou joinUntil, appelez toujours throwIfFailed() ou lisez result() avant de faire confiance à la valeur d'une sous-tâche. Omettre cette étape peut masquer des échecs.

Arrêt propre garanti

Quelle que soit la manière dont un scope se termine — normalement, à la suite d'un échec ou après un délai d'attente — la fermeture du bloc try avec gestion automatique des ressources garantit que le fil d'exécution de chaque sous-tâche est terminé. Il n'y a ni fuite ni tâche orpheline.

Vérification rapide

Rappelez-vous comment les sous-tâches sœurs sont arrêtées.

Récapitulatif

Vous avez appris à gérer les erreurs et les annulations :

  • Les exceptions apparaissent lors de l'appel à throwIfFailed() ou result()
  • Transformez les causes en exceptions personnalisées avec throwIfFailed(mapper)
  • L'annulation fonctionne par interruption du fil d'exécution ; écrivez des tâches coopératives
  • joinUntil impose une échéance au groupe
  • La fermeture du scope effectue toujours le nettoyage

Le cours sur la concurrence structurée est maintenant terminé.

Gratuit pour commencer

Apprends Java avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
104
Leçons
374

Questions Fréquemment Posées

La leçon « Gestion des erreurs et annulation » est-elle gratuite ?

Oui — le texte complet de « Gestion des erreurs et annulation » 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 « Gestion des erreurs et annulation » ?

Propagez proprement les échecs 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 4 sur 4.

Combien de temps prend la leçon « Gestion des erreurs et annulation » ?

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. Modèle de concurrence structurée
  2. StructuredTaskScope
  3. Arrêt en cas d’échec ou de réussite
  4. Gestion des erreurs et annulation
← Retour à Java Academy