Future og feilhåndtering
Bruk Future.get med tidsavbrudd, håndter ExecutionException og avbryt kjørende oppgaver.
Future og feilhåndtering er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva er Future?
En Future<V> representerer resultatet som fortsatt ventes på fra en asynkron beregning. Den tilbyr metoder for å kontrollere om beregningen er fullført, vente på resultatet og håndtere feil.
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();future.get() med tidsavbrudd
Foretrekk alltid varianten med tidsavbrudd for å unngå at kjøringen blir hengende på ubestemt tid:
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
Hvis oppgaven kastet et unntak, pakker future.get() det inn i ExecutionException. Pakk det ut med 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
}Avbryte en Future
cancel(mayInterruptIfRunning) forsøker å avbryte oppgaven. Metoden returnerer true hvis avbrytningen lykkes. Hvis mayInterruptIfRunning er true, sendes et interrupt-signal til tråden som kjører.
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()); // trueisCancelled kontra isDone
isDone() returnerer true hvis oppgaven ble fullført normalt, kastet et unntak eller ble avbrutt. isCancelled() returnerer true bare hvis oppgaven ble avbrutt.
// 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()); // falseCompletionService for resultater som blir tilgjengelige først
ExecutorCompletionService pakker inn en pool og tilbyr en take()-metode for å hente den neste fullførte Future-en (i fullføringsrekkefølge, ikke innsendingsrekkefølge):
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());
}Trygg håndtering av flere Futures
Ved innsamling av resultater fra mange futures bør De iterere gjennom dem og håndtere unntak for hver enkelt Future:
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() etter avslutning av poolen
Innsending etter shutdown() kaster RejectedExecutionException. Futures som ble sendt inn FØR avslutningen, kan likevel hentes etter at poolen er avsluttet:
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: Manuell Future
FutureTask<V> implementerer både Runnable og Future<V> — nyttig når De trenger en Future uten en ExecutorService:
FutureTask<String> task = new FutureTask<>(() -> "computed");
new Thread(task).start(); // run in any thread
System.out.println(task.get()); // computedNytt forsøk-mønster med Future
Implementer enkel logikk for nye forsøk rundt 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
}
}Begrensninger ved Future
java.util.concurrent.Future har begrensninger:
- Ingen tilbakekallingsfunksjoner — De må blokkere med get()
- Kan ikke lenke sammen transformasjoner
- Kan ikke kombinere flere futures
Bruk CompletableFuture (i neste kurs) for reaktiv, ikke-blokkerende komposisjon.
Kort kontrollspørsmål
En oppgave kaster et unntak. Hvilket unntak kastes når De kaller future.get()?
Oppsummering: Future og feilhåndtering
Viktig å huske:
- future.get() blokkerer; bruk alltid varianten med tidsavbrudd
- ExecutionException pakker inn unntak fra oppgaven; pakk dem ut med getCause()
- cancel(true) sender et interrupt-signal; isDone/isCancelled brukes til å kontrollere status
- ExecutorCompletionService.take() henter futures i fullføringsrekkefølge
- FutureTask implementerer både Runnable og Future
Lær deg Java med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 104
- Leksjoner
- 374
Ofte stilte spørsmål
Er leksjonen «Future og feilhåndtering» gratis?
Ja – hele teksten i «Future og feilhåndtering» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Future og feilhåndtering»?
Bruk Future.get med tidsavbrudd, håndter ExecutionException og avbryt kjørende oppgaver. Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Java Academy?
Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Future og feilhåndtering»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?
Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- ExecutorService og trådpooltyper
- Sende inn oppgaver: Runnable kontra Callable
- Future og feilhåndtering
- ScheduledExecutorService for gjentakende oppgaver