Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Completablefuture | Bästa Praxis För Multitrådning
Multitrådning i Java

bookCompletablefuture

Det finns ett sista steg kvar! I detta kapitel kommer vi att titta på den huvudsakliga asynkrona klassen CompletableFuture.

Låt oss använda en verklig analogi. Du beställer en taxi via en app (skapa uppgift). Medan du väntar kan appen ge uppdateringar om bilens position eller beräknad ankomsttid (resultathantering). Om det uppstår problem som förseningar eller avbokningar kommer appen att meddela dig och föreslå alternativ (undantagshantering).

Huvudsakliga metoder

Den första frågan du kanske ställer är hur man startar en uppgift med CompletableFuture. För att göra detta kan du använda metoden supplyAsync(), som är utformad för att köra en uppgift som returnerar resultatet asynkront.

Main.java

Main.java

copy
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 också metoden thenAccept(), som hanterar värdet som returneras från CompletableFuture i asynkron kod. Den returnerar inget; den är användbar när du behöver ta emot ett svar och bearbeta det på något sätt.

Note
Notera

I vårt exempel kör vi uppgiften asynkront, och future.thenAccept() tar emot svaret från lambdan, vilket vi sedan kan använda för att skriva ut till konsolen.

Det finns en liknande metod, thenApply(), som fungerar som thenAccept() men hämtar resultatet av den asynkrona uppgiften och returnerar ett nytt resultat.

Main.java

Main.java

copy
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: });

Vad händer om vi inte vill hämta resultatet av den asynkrona uppgiften utan bara vill bli notifierade när den har slutförts?

För detta kan vi använda thenRun(), som körs efter att den asynkrona uppgiften är klar.

Main.java

Main.java

copy
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 också hämta resultatet av en asynkron uppgift genom att blockera den aktuella tråden tills uppgiften är slutförd. För detta ändamål använder vi metoden get().

Main.java

Main.java

copy
1234567
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }

Det finns också en metod join(), som också pausar den aktuella tråden och väntar på att det asynkrona uppdraget ska slutföras. Dock är skillnaden mellan join() och get() att de kastar olika undantag.

Main.java

Main.java

copy
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 hanterar inte undantaget här eftersom metoden join() kastar ett okontrollerat CompletionException.

Kombinera uppgifter och kedja dem tillsammans

Vi kan kombinera uppgifter i CompletableFuture med hjälp av thenCompose() som kombinerar två beroende uppgifter.

Main.java

Main.java

copy
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 hämtar först bokdata asynkront med metoden getBookDetails(), och använder sedan resultatet för att utföra nästa asynkrona uppgift—att hämta författardata via metoden getAuthorDetails(). När båda uppgifterna är klara visas resultatet (författarinformation) i konsolen.

Vi kan också sammanfoga resultaten av två uppgifter med hjälp av metoden thenCombine(). Den kör båda uppgifterna samtidigt och kombinerar deras resultat när båda uppgifterna är färdiga.

Main.java

Main.java

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

Denna kod hämtar asynkront två tal, summerar dem och skriver ut resultatet till konsolen.

Vi kan också vänta på att alla uppgifter ska bli klara med metoden allOf(), eller någon av dem med metoden anyOf().

Main.java

Main.java

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

Hur hanterar du fel och vad är en timeout?

Kort klipp från videon

  • handle(): Bearbetar resultatet eller hanterar eventuella undantag som kastas av CompletableFuture;
  • exceptionally(): Hanterar undantag som uppstår under körningen av CompletableFuture;
  • completeOnTimeout(): Avslutar CompletableFuture med ett angivet värde om den inte avslutas i tid.
Note
Notering

CompletableFuture förenklar hanteringen av asynkrona uppgifter och bearbetning av deras resultat, vilket gör det till ett kraftfullt verktyg för utveckling av moderna applikationer.

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 6

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Suggested prompts:

What are some practical examples of using CompletableFuture in real applications?

Can you explain the difference between thenAccept(), thenApply(), and thenRun()?

How do you handle exceptions when working with CompletableFuture?

Awesome!

Completion rate improved to 3.33

bookCompletablefuture

Svep för att visa menyn

Det finns ett sista steg kvar! I detta kapitel kommer vi att titta på den huvudsakliga asynkrona klassen CompletableFuture.

Låt oss använda en verklig analogi. Du beställer en taxi via en app (skapa uppgift). Medan du väntar kan appen ge uppdateringar om bilens position eller beräknad ankomsttid (resultathantering). Om det uppstår problem som förseningar eller avbokningar kommer appen att meddela dig och föreslå alternativ (undantagshantering).

Huvudsakliga metoder

Den första frågan du kanske ställer är hur man startar en uppgift med CompletableFuture. För att göra detta kan du använda metoden supplyAsync(), som är utformad för att köra en uppgift som returnerar resultatet asynkront.

Main.java

Main.java

copy
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 också metoden thenAccept(), som hanterar värdet som returneras från CompletableFuture i asynkron kod. Den returnerar inget; den är användbar när du behöver ta emot ett svar och bearbeta det på något sätt.

Note
Notera

I vårt exempel kör vi uppgiften asynkront, och future.thenAccept() tar emot svaret från lambdan, vilket vi sedan kan använda för att skriva ut till konsolen.

Det finns en liknande metod, thenApply(), som fungerar som thenAccept() men hämtar resultatet av den asynkrona uppgiften och returnerar ett nytt resultat.

Main.java

Main.java

copy
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: });

Vad händer om vi inte vill hämta resultatet av den asynkrona uppgiften utan bara vill bli notifierade när den har slutförts?

För detta kan vi använda thenRun(), som körs efter att den asynkrona uppgiften är klar.

Main.java

Main.java

copy
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 också hämta resultatet av en asynkron uppgift genom att blockera den aktuella tråden tills uppgiften är slutförd. För detta ändamål använder vi metoden get().

Main.java

Main.java

copy
1234567
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }

Det finns också en metod join(), som också pausar den aktuella tråden och väntar på att det asynkrona uppdraget ska slutföras. Dock är skillnaden mellan join() och get() att de kastar olika undantag.

Main.java

Main.java

copy
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 hanterar inte undantaget här eftersom metoden join() kastar ett okontrollerat CompletionException.

Kombinera uppgifter och kedja dem tillsammans

Vi kan kombinera uppgifter i CompletableFuture med hjälp av thenCompose() som kombinerar två beroende uppgifter.

Main.java

Main.java

copy
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 hämtar först bokdata asynkront med metoden getBookDetails(), och använder sedan resultatet för att utföra nästa asynkrona uppgift—att hämta författardata via metoden getAuthorDetails(). När båda uppgifterna är klara visas resultatet (författarinformation) i konsolen.

Vi kan också sammanfoga resultaten av två uppgifter med hjälp av metoden thenCombine(). Den kör båda uppgifterna samtidigt och kombinerar deras resultat när båda uppgifterna är färdiga.

Main.java

Main.java

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

Denna kod hämtar asynkront två tal, summerar dem och skriver ut resultatet till konsolen.

Vi kan också vänta på att alla uppgifter ska bli klara med metoden allOf(), eller någon av dem med metoden anyOf().

Main.java

Main.java

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

Hur hanterar du fel och vad är en timeout?

Kort klipp från videon

  • handle(): Bearbetar resultatet eller hanterar eventuella undantag som kastas av CompletableFuture;
  • exceptionally(): Hanterar undantag som uppstår under körningen av CompletableFuture;
  • completeOnTimeout(): Avslutar CompletableFuture med ett angivet värde om den inte avslutas i tid.
Note
Notering

CompletableFuture förenklar hanteringen av asynkrona uppgifter och bearbetning av deras resultat, vilket gör det till ett kraftfullt verktyg för utveckling av moderna applikationer.

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 6
some-alt