Completablefuture
Det er ett siste sprang igjen! I dette kapittelet skal vi se på hovedklassen for asynkronitet, CompletableFuture.
La oss bruke en virkelighetsnær analogi. Du bestiller en taxi via en app (oppgaveopprettelse). Mens du venter, kan appen gi oppdateringer om bilens posisjon eller estimert ankomsttid (resultatbehandling). Dersom det oppstår problemer som forsinkelser eller kanselleringer, vil appen varsle deg og foreslå alternativer (unntakshåndtering).
Hovedmetoder
Det første spørsmålet du kanskje stiller er hvordan man starter en oppgave med CompletableFuture. For dette kan du bruke metoden supplyAsync(), som er laget for å utføre en oppgave som returnerer resultatet asynkront.
Main.java
12345678910// Creating an asynchronous task CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Result"; // Result }); // Processing the result after the task completes future.thenAccept(result -> { // Print the result to the console System.out.println("Result received: " + result); // Result received: });
Vi har også thenAccept()-metoden, som håndterer verdien returnert fra CompletableFuture i asynkron kode. Den returnerer ingenting; den er nyttig når du trenger å motta et svar og behandle det på en eller annen måte.
I vårt eksempel kjører vi oppgaven asynkront, og future.thenAccept() mottar svaret fra lambdaen, som vi deretter kan bruke til å skrive ut til konsollen.
Det finnes en lignende metode, thenApply(), som fungerer som thenAccept(), men henter resultatet av den asynkrone oppgaven og returnerer et nytt resultat.
Main.java
12345678910// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Transforming the result to uppercase CompletableFuture<String> transformedFuture = future.thenApply(result -> result.toUpperCase()); // Printing the transformed result to the console transformedFuture.thenAccept(result -> { System.out.println("Transformed result: " + result); // Transformed result: });
Hva om vi ikke ønsker å hente resultatet av den asynkrone oppgaven, men bare vil bli varslet når den er ferdig?
Til dette kan vi bruke thenRun(), som kjøres etter at den asynkrone oppgaven er fullført.
Main.java
12345678// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Running a task when the previous task completes future.thenRun(() -> { // Print message to the console indicating that the task is complete System.out.println("Task completed!"); // Task completed! });
Vi kan også hente resultatet av en asynkron oppgave ved å blokkere den nåværende tråden til oppgaven er fullført. Til dette formålet bruker vi metoden get().
Main.java
1234567CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
Det finnes også en metode join(), som også pauser den nåværende tråden og venter på at den asynkrone oppgaven skal fullføres. Forskjellen mellom join() og get() er imidlertid at de kaster forskjellige unntak.
Main.java
12345// Create a `CompletableFuture` that asynchronously executes a task and returns the string "Hello World". CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); // The `join()` method blocks the current thread until the task is completed and returns the result "Hello World". String result = completableFuture.join();
Vi håndterer ikke unntaket her fordi join()-metoden kaster et ukontrollert CompletionException.
Kombinere oppgaver og kjede dem sammen
Vi kan kombinere oppgaver i CompletableFuture ved å bruke thenCompose(), som kombinerer to avhengige oppgaver.
Main.java
12345678910111213141516171819202122232425// Method to get book details from a remote service public CompletableFuture<String> getBookDetails() { return CompletableFuture.supplyAsync(() -> { // Request to a remote service to get book details return "Book Details"; // Placeholder for book details }); } // Method to get author details from a remote service public CompletableFuture<String> getAuthorDetails(String bookDetails) { return CompletableFuture.supplyAsync(() -> { // Request to another service to get author details return bookDetails + " Author"; // Placeholder for author details }); } // Combine two asynchronous tasks: get book details and then get author details CompletableFuture<String> result = getBookDetails() .thenCompose(book -> getAuthorDetails(book)); // Process the result and print the author details to the console result.thenAccept(author -> { // Print the author details to the console System.out.println("Author: " + author); // Author details });
Vi henter først bokdata asynkront ved å bruke getBookDetails()-metoden, og bruker deretter resultatet til å utføre neste asynkrone oppgave—å hente forfatterdata gjennom getAuthorDetails()-metoden. Etter at begge oppgavene er fullført, vises resultatet (forfatterinformasjon) i konsollen.
Vi kan også slå sammen resultatene av to oppgaver ved å bruke thenCombine()-metoden. Den kjører begge oppgavene samtidig og kombinerer resultatene når begge oppgavene er fullført.
Main.java
123456789101112// CompletableFuture for adding two numbers CompletableFuture<Double> firstNumberFuture = CompletableFuture.supplyAsync(() -> 50.0); CompletableFuture<Double> secondNumberFuture = CompletableFuture.supplyAsync(() -> 30.0); // Combine the two futures by adding their results CompletableFuture<Double> sumFuture = firstNumberFuture.thenCombine(secondNumberFuture, (first, second) -> first + second); // Print the result of the addition to the console sumFuture.thenAccept(sum -> { System.out.println("Sum: " + sum); // Sum: 80.0 });
Denne koden henter asynkront to tall, summerer dem og skriver resultatet til konsollen.
Vi kan også vente på at alle oppgaver skal fullføres ved å bruke allOf()-metoden, eller hvilken som helst av dem ved å bruke anyOf()-metoden.
Main.java
1234567891011121314151617181920CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> { // Task 1 System.out.println("Task 1 completed"); }); CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> { // Task 2 System.out.println("Task 2 completed"); }); // Combine both futures and wait for both tasks to complete CompletableFuture<Void> combinedFuture1 = CompletableFuture.allOf(future1, future2); // Combine both futures and proceed as soon as any one task completes CompletableFuture<Object> combinedFuture2 = CompletableFuture.anyOf(future1, future2); // Print a message after all tasks are completed combinedFuture1.thenRun(() -> { System.out.println("All tasks completed"); });
Hvordan håndterer du feil og hva er en timeout?
Kort klipp fra videoen
handle(): Behandler resultatet eller håndterer eventuelle unntak kastet avCompletableFuture;exceptionally(): Håndterer unntak som oppstår under utførelsen avCompletableFuture;completeOnTimeout(): FullførerCompletableFuturemed en angitt verdi hvis den ikke fullføres innen tidsfristen.
CompletableFuture gjør det enkelt å håndtere asynkrone oppgaver og behandle resultatene deres, noe som gjør det til et kraftig verktøy for utvikling av moderne applikasjoner.
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår
Awesome!
Completion rate improved to 3.33
Completablefuture
Sveip for å vise menyen
Det er ett siste sprang igjen! I dette kapittelet skal vi se på hovedklassen for asynkronitet, CompletableFuture.
La oss bruke en virkelighetsnær analogi. Du bestiller en taxi via en app (oppgaveopprettelse). Mens du venter, kan appen gi oppdateringer om bilens posisjon eller estimert ankomsttid (resultatbehandling). Dersom det oppstår problemer som forsinkelser eller kanselleringer, vil appen varsle deg og foreslå alternativer (unntakshåndtering).
Hovedmetoder
Det første spørsmålet du kanskje stiller er hvordan man starter en oppgave med CompletableFuture. For dette kan du bruke metoden supplyAsync(), som er laget for å utføre en oppgave som returnerer resultatet asynkront.
Main.java
12345678910// Creating an asynchronous task CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Result"; // Result }); // Processing the result after the task completes future.thenAccept(result -> { // Print the result to the console System.out.println("Result received: " + result); // Result received: });
Vi har også thenAccept()-metoden, som håndterer verdien returnert fra CompletableFuture i asynkron kode. Den returnerer ingenting; den er nyttig når du trenger å motta et svar og behandle det på en eller annen måte.
I vårt eksempel kjører vi oppgaven asynkront, og future.thenAccept() mottar svaret fra lambdaen, som vi deretter kan bruke til å skrive ut til konsollen.
Det finnes en lignende metode, thenApply(), som fungerer som thenAccept(), men henter resultatet av den asynkrone oppgaven og returnerer et nytt resultat.
Main.java
12345678910// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Transforming the result to uppercase CompletableFuture<String> transformedFuture = future.thenApply(result -> result.toUpperCase()); // Printing the transformed result to the console transformedFuture.thenAccept(result -> { System.out.println("Transformed result: " + result); // Transformed result: });
Hva om vi ikke ønsker å hente resultatet av den asynkrone oppgaven, men bare vil bli varslet når den er ferdig?
Til dette kan vi bruke thenRun(), som kjøres etter at den asynkrone oppgaven er fullført.
Main.java
12345678// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Running a task when the previous task completes future.thenRun(() -> { // Print message to the console indicating that the task is complete System.out.println("Task completed!"); // Task completed! });
Vi kan også hente resultatet av en asynkron oppgave ved å blokkere den nåværende tråden til oppgaven er fullført. Til dette formålet bruker vi metoden get().
Main.java
1234567CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
Det finnes også en metode join(), som også pauser den nåværende tråden og venter på at den asynkrone oppgaven skal fullføres. Forskjellen mellom join() og get() er imidlertid at de kaster forskjellige unntak.
Main.java
12345// Create a `CompletableFuture` that asynchronously executes a task and returns the string "Hello World". CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); // The `join()` method blocks the current thread until the task is completed and returns the result "Hello World". String result = completableFuture.join();
Vi håndterer ikke unntaket her fordi join()-metoden kaster et ukontrollert CompletionException.
Kombinere oppgaver og kjede dem sammen
Vi kan kombinere oppgaver i CompletableFuture ved å bruke thenCompose(), som kombinerer to avhengige oppgaver.
Main.java
12345678910111213141516171819202122232425// Method to get book details from a remote service public CompletableFuture<String> getBookDetails() { return CompletableFuture.supplyAsync(() -> { // Request to a remote service to get book details return "Book Details"; // Placeholder for book details }); } // Method to get author details from a remote service public CompletableFuture<String> getAuthorDetails(String bookDetails) { return CompletableFuture.supplyAsync(() -> { // Request to another service to get author details return bookDetails + " Author"; // Placeholder for author details }); } // Combine two asynchronous tasks: get book details and then get author details CompletableFuture<String> result = getBookDetails() .thenCompose(book -> getAuthorDetails(book)); // Process the result and print the author details to the console result.thenAccept(author -> { // Print the author details to the console System.out.println("Author: " + author); // Author details });
Vi henter først bokdata asynkront ved å bruke getBookDetails()-metoden, og bruker deretter resultatet til å utføre neste asynkrone oppgave—å hente forfatterdata gjennom getAuthorDetails()-metoden. Etter at begge oppgavene er fullført, vises resultatet (forfatterinformasjon) i konsollen.
Vi kan også slå sammen resultatene av to oppgaver ved å bruke thenCombine()-metoden. Den kjører begge oppgavene samtidig og kombinerer resultatene når begge oppgavene er fullført.
Main.java
123456789101112// CompletableFuture for adding two numbers CompletableFuture<Double> firstNumberFuture = CompletableFuture.supplyAsync(() -> 50.0); CompletableFuture<Double> secondNumberFuture = CompletableFuture.supplyAsync(() -> 30.0); // Combine the two futures by adding their results CompletableFuture<Double> sumFuture = firstNumberFuture.thenCombine(secondNumberFuture, (first, second) -> first + second); // Print the result of the addition to the console sumFuture.thenAccept(sum -> { System.out.println("Sum: " + sum); // Sum: 80.0 });
Denne koden henter asynkront to tall, summerer dem og skriver resultatet til konsollen.
Vi kan også vente på at alle oppgaver skal fullføres ved å bruke allOf()-metoden, eller hvilken som helst av dem ved å bruke anyOf()-metoden.
Main.java
1234567891011121314151617181920CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> { // Task 1 System.out.println("Task 1 completed"); }); CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> { // Task 2 System.out.println("Task 2 completed"); }); // Combine both futures and wait for both tasks to complete CompletableFuture<Void> combinedFuture1 = CompletableFuture.allOf(future1, future2); // Combine both futures and proceed as soon as any one task completes CompletableFuture<Object> combinedFuture2 = CompletableFuture.anyOf(future1, future2); // Print a message after all tasks are completed combinedFuture1.thenRun(() -> { System.out.println("All tasks completed"); });
Hvordan håndterer du feil og hva er en timeout?
Kort klipp fra videoen
handle(): Behandler resultatet eller håndterer eventuelle unntak kastet avCompletableFuture;exceptionally(): Håndterer unntak som oppstår under utførelsen avCompletableFuture;completeOnTimeout(): FullførerCompletableFuturemed en angitt verdi hvis den ikke fullføres innen tidsfristen.
CompletableFuture gjør det enkelt å håndtere asynkrone oppgaver og behandle resultatene deres, noe som gjør det til et kraftig verktøy for utvikling av moderne applikasjoner.
Takk for tilbakemeldingene dine!