Gestione degli errori e annullamento
Propagare gli errori in modo ordinato
Gestione degli errori e annullamento è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.
Errori in un albero di attività
Quando le sottoattività vengono eseguite in parallelo, gli errori possono verificarsi in qualsiasi ramo. La concorrenza strutturata offre un modo disciplinato per propagare questi errori al livello superiore.
Questa lezione tratta eccezioni, annullamento, interruzioni e timeout.
Dove emergono le eccezioni
Una sottoattività che genera un'eccezione non arresta immediatamente il programma. L'eccezione viene acquisita dal suo handle Subtask. Il punto in cui emerge dipende dalla politica:
ShutdownOnFailure: inthrowIfFailed()ShutdownOnSuccess: inresult()se nessuna sottoattività ha avuto esito positivo
Propagazione con throwIfFailed
Qui una sottoattività fallisce. throwIfFailed() la rilancia racchiusa in ExecutionException, che viene catturata in 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());
}
}
}Trasformazione in un'eccezione personalizzata
throwIfFailed accetta una funzione per racchiudere la causa nel tipo di eccezione scelto, mantenendo pulita la sua 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());
}
}
}Annullamento automatico
Quando una sottoattività fallisce con ShutdownOnFailure, lo scope annulla le sottoattività sorelle interrompendone i thread. Non deve scrivere personalmente alcun codice di annullamento.
Questo evita lavoro sprecato e attività lasciate in sospeso.
L'interruzione è il meccanismo
L'annullamento funziona interrompendo il thread virtuale della sottoattività. Il codice cooperativo dovrebbe:
- Lasciare che le chiamate bloccanti generino
InterruptedException - Verificare periodicamente
Thread.currentThread().isInterrupted()nei cicli lunghi
Rispondere all'interruzione
Questa attività verifica il flag di interruzione in un ciclo, così può terminare prima quando lo scope viene arrestato.
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();
}
}Scadenze con joinUntil
Per limitare il tempo totale, utilizzi joinUntil(Instant). Se la scadenza viene raggiunta prima che tutte le sottoattività terminino, genera TimeoutException e lo scope arresta le attività rimanenti.
Struttura di un esempio con timeout
Una tipica distribuzione di lavoro protetta da timeout ha questo aspetto. La scadenza si applica all'intero gruppo, non a ogni singola sottoattività.
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");
}
}
}Ricontrolli sempre dopo join
La regola è: dopo join() o joinUntil, chiami sempre throwIfFailed() o legga result() prima di considerare attendibile il valore di una sottoattività. Saltare questo passaggio può nascondere gli errori.
Arresto pulito garantito
Indipendentemente da come termina uno scope, normalmente, per un errore o per un timeout, la chiusura del blocco try-with-resources garantisce che ogni thread delle sottoattività sia terminato. Non ci sono perdite né attività orfane.
Verifica rapida
Ricordi come vengono arrestate le sottoattività sorelle.
Riepilogo
Ha imparato a gestire errori e annullamenti:
- Le eccezioni emergono in
throwIfFailed()oresult() - Trasformi le cause in eccezioni personalizzate tramite
throwIfFailed(mapper) - L'annullamento avviene tramite interruzione del thread; scriva attività cooperative
joinUntilimpone una scadenza al gruppo- La chiusura dello scope esegue sempre la pulizia
Il corso sulla concorrenza strutturata è completo.
Domande Frequenti
La lezione «Gestione degli errori e annullamento» è gratuita?
Sì — il testo completo di «Gestione degli errori e annullamento» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.
Cosa imparerò in «Gestione degli errori e annullamento»?
Propagare gli errori in modo ordinato Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Java Academy?
Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Gestione degli errori e annullamento»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Java Academy?
Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Il modello di concorrenza strutturata
- StructuredTaskScope
- Arresto in caso di errore e successo
- Gestione degli errori e annullamento