Java Academy · Lektion

Felhantering och avbrytning

Vidarebefordra fel på ett tydligt sätt.

Lektion 4 av 413 steg

Felhantering och avbrytning är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.

Fel i ett träd av uppgifter

När deluppgifter körs samtidigt kan fel uppstå i vilken gren som helst. Strukturerad samtidighet ger er ett disciplinerat sätt att propagera dessa fel upp till den överordnade uppgiften.

I den här lektionen behandlas undantag, avbrytning, avbrott och tidsgränser.

Var undantag blir synliga

En deluppgift som kastar ett undantag kraschar inte programmet omedelbart. Undantaget fångas upp av dess Subtask-handtag. Var det blir synligt beror på policyn:

  • ShutdownOnFailure: vid throwIfFailed()
  • ShutdownOnSuccess: vid result() om ingen lyckades

Propagera med throwIfFailed

Här misslyckas en deluppgift. throwIfFailed() kastar undantaget igen, omslutet i ExecutionException, vilket vi fångar i 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());
        }
    }
}

Mappa till ett anpassat undantag

throwIfFailed accepterar en funktion som omsluter orsaken i er egen undantagstyp, så att ert API förblir rent.

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());
        }
    }
}

Automatisk avbrytning

När en deluppgift misslyckas under ShutdownOnFailure avbryter scopet syskonen genom att avbryta deras trådar. Ni behöver inte skriva någon avbrytningskod själva.

Detta förhindrar slösat arbete och kvarhängande uppgifter.

Avbrott är mekanismen

Avbrytning fungerar genom att den virtuella tråden för deluppgiften avbryts. Samarbetsbaserad kod bör:

  • låta blockerande anrop kasta InterruptedException
  • regelbundet kontrollera Thread.currentThread().isInterrupted() i långa loopar

Reagera på avbrott

Den här uppgiften kontrollerar avbrottsflaggan i en loop, så att den kan avslutas tidigt när scopet stängs ner.

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();
    }
}

Tidsgränser med joinUntil

Begränsa den totala tiden genom att använda joinUntil(Instant). Om tidsgränsen passeras innan alla deluppgifter är klara kastar det TimeoutException, och scopet stänger ner resten.

Utformning av ett tidsgränsskyddat exempel

En typisk förgrening med tidsgräns ser ut så här. Tidsgränsen gäller för hela gruppen, inte för varje deluppgift separat.

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");
        }
    }
}

Kontrollera alltid igen efter join

Arbetsregeln är: efter join() eller joinUntil ska ni alltid anropa throwIfFailed() eller läsa result() innan ni litar på något värde från en deluppgift. Om ni hoppar över detta kan fel döljas.

Ren avslutning garanteras

Oavsett hur ett scope avslutas – normalt, på grund av ett fel eller på grund av en tidsgräns – garanterar den avslutande delen av try-with-resources-blocket att tråden för varje deluppgift är klar. Det finns inga läckor och inga övergivna trådar.

Snabbtest

Kom ihåg hur syskonens deluppgifter stoppas.

Sammanfattning

Ni har lärt er felhantering och avbrytning:

  • Undantag blir synliga vid throwIfFailed() eller result()
  • Mappa orsaker till anpassade undantag via throwIfFailed(mapper)
  • Avbrytning fungerar genom trådarnas avbrott; skriv samarbetsbaserade uppgifter
  • joinUntil tillämpar en tidsgräns för gruppen
  • När scopet stängs sker alltid en städning

Därmed är kursen i strukturerad samtidighet slutförd.

Gratis att börja

Lär dig Java med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
104
Lektioner
374

Vanliga frågor

Är lektionen ”Felhantering och avbrytning” gratis?

Ja – hela texten till ”Felhantering och avbrytning” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Felhantering och avbrytning”?

Vidarebefordra fel på ett tydligt sätt. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Java Academy?

Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”Felhantering och avbrytning”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Java Academy-lektionen?

Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Modellen för strukturerad samtidighet
  2. StructuredTaskScope
  3. Avslut vid fel och framgång
  4. Felhantering och avbrytning
← Tillbaka till Java Academy