Completablefuture
Der er ét sidste spring tilbage! I dette kapitel ser vi på den primære asynkroniklasse CompletableFuture.
Lad os bruge en virkelighedsnær analogi. Du bestiller en taxa via en app (oprettelse af opgave). Mens du venter, kan appen give opdateringer om bilens placering eller den forventede ankomsttid (resultatbehandling). Hvis der opstår problemer som forsinkelser eller aflysninger, vil appen informere dig og foreslå alternativer (undtagelseshåndtering).
Hovedmetoder
Det første spørgsmål, du måske stiller, er, hvordan man starter en opgave ved hjælp af CompletableFuture. For at gøre dette kan du bruge metoden supplyAsync(), som er designet til at udføre en opgave, der 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å metoden thenAccept(), som håndterer værdien returneret fra CompletableFuture i asynkron kode. Den returnerer ikke noget; den er nyttig, når du skal acceptere et svar og behandle det på en eller anden måde.
I vores eksempel kører vi opgaven asynkront, og future.thenAccept() modtager svaret fra lambdaen, som vi derefter kan bruge til at udskrive til konsollen.
Der findes en lignende metode, thenApply(), som fungerer som thenAccept(), men modtager resultatet af den asynkrone opgave og returnerer et nyt 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: });
Hvad nu hvis vi ikke ønsker at modtage resultatet af den asynkrone opgave, men blot vil underrettes, når den er afsluttet?
Til dette kan vi bruge thenRun(), som udføres efter at den asynkrone opgave er færdig.
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! });
Resultatet af en asynkron opgave kan også hentes ved at blokere den aktuelle tråd, indtil opgaven er fuldført. Til dette formål anvendes metoden get().
Main.java
1234567CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
Der findes også en metode join(), som ligeledes pauser den aktuelle tråd og venter på, at asynkrone opgave fuldføres. Forskellen mellem join() og get() er dog, at de kaster forskellige undtagelser.
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 undtagelsen her, fordi join()-metoden kaster en unchecked CompletionException.
Kombinering af opgaver og kædning af dem sammen
Det er muligt at kombinere opgaver i CompletableFuture ved hjælp af thenCompose(), som kombinerer 2 afhængige opgaver.
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 });
Først hentes bogdata asynkront ved hjælp af getBookDetails()-metoden, hvorefter resultatet bruges til at udføre den næste asynkrone opgave—hentning af forfatterdata gennem getAuthorDetails()-metoden. Når begge opgaver er fuldført, vises resultatet (forfatterinformation) på konsollen.
Vi kan også flette resultaterne af to opgaver ved hjælp af thenCombine() metoden. Den udfører begge opgaver samtidigt og kombinerer deres resultater, når begge opgaver er fuldførte.
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 kode henter asynkront to tal, summerer dem og udskriver resultatet til konsollen.
Vi kan også vente på, at alle opgaver er fuldførte ved hjælp af allOf() metoden, eller på en hvilken som helst af dem med 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åndteres fejl, og hvad er en timeout?
Kort klip fra videoen
handle(): Behandler resultatet eller håndterer eventuelle undtagelser, der kastes afCompletableFuture;exceptionally(): Håndterer undtagelser, der opstår under udførelsen afCompletableFuture;completeOnTimeout(): FuldførerCompletableFuturemed en angivet værdi hvis den ikke fuldføres inden timeout.
CompletableFuture gør det nemt at administrere asynkrone opgaver og behandle deres resultater, hvilket gør det til et effektivt værktøj til udvikling af moderne applikationer.
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat
Awesome!
Completion rate improved to 3.33
Completablefuture
Stryg for at vise menuen
Der er ét sidste spring tilbage! I dette kapitel ser vi på den primære asynkroniklasse CompletableFuture.
Lad os bruge en virkelighedsnær analogi. Du bestiller en taxa via en app (oprettelse af opgave). Mens du venter, kan appen give opdateringer om bilens placering eller den forventede ankomsttid (resultatbehandling). Hvis der opstår problemer som forsinkelser eller aflysninger, vil appen informere dig og foreslå alternativer (undtagelseshåndtering).
Hovedmetoder
Det første spørgsmål, du måske stiller, er, hvordan man starter en opgave ved hjælp af CompletableFuture. For at gøre dette kan du bruge metoden supplyAsync(), som er designet til at udføre en opgave, der 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å metoden thenAccept(), som håndterer værdien returneret fra CompletableFuture i asynkron kode. Den returnerer ikke noget; den er nyttig, når du skal acceptere et svar og behandle det på en eller anden måde.
I vores eksempel kører vi opgaven asynkront, og future.thenAccept() modtager svaret fra lambdaen, som vi derefter kan bruge til at udskrive til konsollen.
Der findes en lignende metode, thenApply(), som fungerer som thenAccept(), men modtager resultatet af den asynkrone opgave og returnerer et nyt 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: });
Hvad nu hvis vi ikke ønsker at modtage resultatet af den asynkrone opgave, men blot vil underrettes, når den er afsluttet?
Til dette kan vi bruge thenRun(), som udføres efter at den asynkrone opgave er færdig.
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! });
Resultatet af en asynkron opgave kan også hentes ved at blokere den aktuelle tråd, indtil opgaven er fuldført. Til dette formål anvendes metoden get().
Main.java
1234567CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
Der findes også en metode join(), som ligeledes pauser den aktuelle tråd og venter på, at asynkrone opgave fuldføres. Forskellen mellem join() og get() er dog, at de kaster forskellige undtagelser.
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 undtagelsen her, fordi join()-metoden kaster en unchecked CompletionException.
Kombinering af opgaver og kædning af dem sammen
Det er muligt at kombinere opgaver i CompletableFuture ved hjælp af thenCompose(), som kombinerer 2 afhængige opgaver.
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 });
Først hentes bogdata asynkront ved hjælp af getBookDetails()-metoden, hvorefter resultatet bruges til at udføre den næste asynkrone opgave—hentning af forfatterdata gennem getAuthorDetails()-metoden. Når begge opgaver er fuldført, vises resultatet (forfatterinformation) på konsollen.
Vi kan også flette resultaterne af to opgaver ved hjælp af thenCombine() metoden. Den udfører begge opgaver samtidigt og kombinerer deres resultater, når begge opgaver er fuldførte.
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 kode henter asynkront to tal, summerer dem og udskriver resultatet til konsollen.
Vi kan også vente på, at alle opgaver er fuldførte ved hjælp af allOf() metoden, eller på en hvilken som helst af dem med 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åndteres fejl, og hvad er en timeout?
Kort klip fra videoen
handle(): Behandler resultatet eller håndterer eventuelle undtagelser, der kastes afCompletableFuture;exceptionally(): Håndterer undtagelser, der opstår under udførelsen afCompletableFuture;completeOnTimeout(): FuldførerCompletableFuturemed en angivet værdi hvis den ikke fuldføres inden timeout.
CompletableFuture gør det nemt at administrere asynkrone opgaver og behandle deres resultater, hvilket gør det til et effektivt værktøj til udvikling af moderne applikationer.
Tak for dine kommentarer!