Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Completablefuture | Monisäikeisyyden Parhaat Käytännöt
Monisäikeisyys Javassa

bookCompletablefuture

Vielä yksi askel jäljellä! Tässä luvussa tarkastellaan pääasiallista asynkronista luokkaa CompletableFuture.

Käytetään tosielämän vertausta. Tilaat taksin sovelluksella (tehtävän luonti). Odottaessasi sovellus voi tarjota päivityksiä auton sijainnista tai arvioidusta saapumisajasta (tuloksen käsittely). Jos ilmenee ongelmia, kuten viivästyksiä tai peruutuksia, sovellus ilmoittaa niistä ja ehdottaa vaihtoehtoja (poikkeusten käsittely).

Päämenetelmät

Ensimmäinen kysymys saattaa olla, kuinka tehtävä käynnistetään käyttäen CompletableFuture-luokkaa. Tätä varten voidaan käyttää supplyAsync() menetelmää, joka on suunniteltu suorittamaan tehtävä ja palauttamaan tuloksen asynkronisesti.

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

Käytettävissä on myös thenAccept() metodi, joka käsittelee CompletableFuture-olion palauttaman arvon asynkronisessa koodissa. Se ei palauta mitään; se on hyödyllinen, kun tarvitsee hyväksyä vastaus ja käsitellä sitä jollain tavalla.

Note
Huomio

Esimerkissämme suoritamme tehtävän asynkronisesti, ja future.thenAccept() saa vastauksen lambda-lausekkeesta, jota voidaan käyttää esimerkiksi tulostamiseen konsoliin.

On olemassa vastaava metodi, thenApply(), joka toimii kuten thenAccept(), mutta saa asynkronisen tehtävän tuloksen ja palauttaa uuden tuloksen.

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

Entä jos emme halua saada asynkronisen tehtävän tulosta, vaan haluamme vain tiedon, kun se on valmistunut?

Tätä varten voidaan käyttää thenRun(), joka suoritetaan, kun asynkroninen tehtävä on valmis.

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

Voimme myös hakea asynkronisen tehtävän tuloksen estämällä nykyisen säikeen kunnes tehtävä on valmistunut. Tätä tarkoitusta varten käytetään get()-metodia.

Main.java

Main.java

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

On olemassa myös metodi join(), joka myös pysäyttää nykyisen säikeen ja odottaa asynkronisen tehtävän valmistumista. Ero join()- ja get()-metodien välillä on kuitenkin siinä, että ne heittävät erilaisia poikkeuksia.

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

Tässä ei käsitellä poikkeusta, koska join()-metodi heittää tarkistamattoman CompletionException-poikkeuksen.

Tehtävien yhdistäminen ja ketjuttaminen

Voimme yhdistää tehtäviä CompletableFuture:n avulla käyttämällä thenCompose()-metodia, joka yhdistää kaksi riippuvaista tehtävää.

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

Ensin haetaan kirjan tiedot asynkronisesti käyttämällä getBookDetails()-metodia, ja tämän jälkeen käytetään tulosta seuraavan asynkronisen tehtävän suorittamiseen—kirjoittajan tietojen hakemiseen getAuthorDetails()-metodin avulla. Kun molemmat tehtävät ovat valmiit, tulos (kirjoittajan tiedot) näytetään konsolissa.

Voimme myös yhdistää kahden tehtävän tulokset käyttämällä thenCombine()-metodia. Se suorittaa molemmat tehtävät rinnakkain ja yhdistää niiden tulokset, kun molemmat tehtävät ovat valmiit.

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

Tämä koodi hakee asynkronisesti kaksi lukua, laskee niiden summan ja tulostaa tuloksen konsoliin.

Voimme myös odottaa, että kaikki tehtävät valmistuvat käyttämällä allOf()-metodia, tai minkä tahansa niistä käyttämällä anyOf()-metodia.

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

Kuinka virheitä käsitellään ja mitä on aikakatkaisu?

Lyhyt katkelma videosta

  • handle(): Käsittelee tuloksen tai käsittelee mahdolliset CompletableFuture-olion heittämät poikkeukset;
  • exceptionally(): Käsittelee poikkeukset, jotka tapahtuvat CompletableFuture-olion suorituksen aikana;
  • completeOnTimeout(): Suorittaa CompletableFuture-olion määritetyllä arvolla jos suoritus ylittää aikarajan ennen valmistumista.
Note
Huomio

CompletableFuture helpottaa asynkronisten tehtävien hallintaa ja niiden tulosten käsittelyä, mikä tekee siitä tehokkaan työkalun nykyaikaisten sovellusten kehittämiseen.

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 4. Luku 6

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

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

Pyyhkäise näyttääksesi valikon

Vielä yksi askel jäljellä! Tässä luvussa tarkastellaan pääasiallista asynkronista luokkaa CompletableFuture.

Käytetään tosielämän vertausta. Tilaat taksin sovelluksella (tehtävän luonti). Odottaessasi sovellus voi tarjota päivityksiä auton sijainnista tai arvioidusta saapumisajasta (tuloksen käsittely). Jos ilmenee ongelmia, kuten viivästyksiä tai peruutuksia, sovellus ilmoittaa niistä ja ehdottaa vaihtoehtoja (poikkeusten käsittely).

Päämenetelmät

Ensimmäinen kysymys saattaa olla, kuinka tehtävä käynnistetään käyttäen CompletableFuture-luokkaa. Tätä varten voidaan käyttää supplyAsync() menetelmää, joka on suunniteltu suorittamaan tehtävä ja palauttamaan tuloksen asynkronisesti.

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

Käytettävissä on myös thenAccept() metodi, joka käsittelee CompletableFuture-olion palauttaman arvon asynkronisessa koodissa. Se ei palauta mitään; se on hyödyllinen, kun tarvitsee hyväksyä vastaus ja käsitellä sitä jollain tavalla.

Note
Huomio

Esimerkissämme suoritamme tehtävän asynkronisesti, ja future.thenAccept() saa vastauksen lambda-lausekkeesta, jota voidaan käyttää esimerkiksi tulostamiseen konsoliin.

On olemassa vastaava metodi, thenApply(), joka toimii kuten thenAccept(), mutta saa asynkronisen tehtävän tuloksen ja palauttaa uuden tuloksen.

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

Entä jos emme halua saada asynkronisen tehtävän tulosta, vaan haluamme vain tiedon, kun se on valmistunut?

Tätä varten voidaan käyttää thenRun(), joka suoritetaan, kun asynkroninen tehtävä on valmis.

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

Voimme myös hakea asynkronisen tehtävän tuloksen estämällä nykyisen säikeen kunnes tehtävä on valmistunut. Tätä tarkoitusta varten käytetään get()-metodia.

Main.java

Main.java

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

On olemassa myös metodi join(), joka myös pysäyttää nykyisen säikeen ja odottaa asynkronisen tehtävän valmistumista. Ero join()- ja get()-metodien välillä on kuitenkin siinä, että ne heittävät erilaisia poikkeuksia.

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

Tässä ei käsitellä poikkeusta, koska join()-metodi heittää tarkistamattoman CompletionException-poikkeuksen.

Tehtävien yhdistäminen ja ketjuttaminen

Voimme yhdistää tehtäviä CompletableFuture:n avulla käyttämällä thenCompose()-metodia, joka yhdistää kaksi riippuvaista tehtävää.

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

Ensin haetaan kirjan tiedot asynkronisesti käyttämällä getBookDetails()-metodia, ja tämän jälkeen käytetään tulosta seuraavan asynkronisen tehtävän suorittamiseen—kirjoittajan tietojen hakemiseen getAuthorDetails()-metodin avulla. Kun molemmat tehtävät ovat valmiit, tulos (kirjoittajan tiedot) näytetään konsolissa.

Voimme myös yhdistää kahden tehtävän tulokset käyttämällä thenCombine()-metodia. Se suorittaa molemmat tehtävät rinnakkain ja yhdistää niiden tulokset, kun molemmat tehtävät ovat valmiit.

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

Tämä koodi hakee asynkronisesti kaksi lukua, laskee niiden summan ja tulostaa tuloksen konsoliin.

Voimme myös odottaa, että kaikki tehtävät valmistuvat käyttämällä allOf()-metodia, tai minkä tahansa niistä käyttämällä anyOf()-metodia.

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

Kuinka virheitä käsitellään ja mitä on aikakatkaisu?

Lyhyt katkelma videosta

  • handle(): Käsittelee tuloksen tai käsittelee mahdolliset CompletableFuture-olion heittämät poikkeukset;
  • exceptionally(): Käsittelee poikkeukset, jotka tapahtuvat CompletableFuture-olion suorituksen aikana;
  • completeOnTimeout(): Suorittaa CompletableFuture-olion määritetyllä arvolla jos suoritus ylittää aikarajan ennen valmistumista.
Note
Huomio

CompletableFuture helpottaa asynkronisten tehtävien hallintaa ja niiden tulosten käsittelyä, mikä tekee siitä tehokkaan työkalun nykyaikaisten sovellusten kehittämiseen.

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 4. Luku 6
some-alt