Je ne comprends pas même si je lis le document officiel de CompletableFuture, donc je comprends la recette inversée Java d'une seule main

Cet article est l'article du 9ème jour de Team Lab Engineering.

Dans cet article, j'écrirai sur Completable Future.

Contexte

Je ne sais même pas si j'appelle le document officiel de Completable Future Comprendre la recette inverse Java d'une seule main

URL de référence Ouvrage de référence

CompletableFuture version anglaise Java11 CompletableFuture version japonaise Java8 [Recette inverse Java](https://www.amazon.co.jp/Java%E9%80%86%E5%BC%95%E3%81%8D%E3%83%AC%E3%82%B7 % E3% 83% 94-% E7% AC% AC2% E7% 89% 88-% E7% AB% B9% E6% B7% BB-% E7% 9B% B4% E6% A8% B9 / dp / 4798158445)

Types de traitement parallèle, différences

Thread: Le traitement effectué dans le thread ne peut plus être repris par la suite.

future: Appel pour obtenir le thread de blocs de méthode

completablefuture: l'appelant n'est pas bloqué

Différence entre puis Appliquer et Accepter

thenApply ・ ・ ・ Le résultat traité dans la méthode peut être passé à la méthode suivante. thenAccept ・ ・ ・ Le résultat traité dans la méthode ne peut pas être passé à la méthode suivante.

puis Appliquer


    CompletableFuture<String> future1 =
        CompletableFuture.supplyAsync(
            () -> {
              //Processus chronophage
              try {
                Thread.sleep(1000);
              } catch (InterruptedException e) {
                e.printStackTrace();
              }
              return "java1";
            });


//puis Appliquer
    future1
        .thenApply(
            res -> {
              return res; //res contient "java1" défini dans le retour de future1
            })
        .thenApply(
            res -> {
              return res; //res contient la valeur de retour "java1" du premier puis Apply
            })
        .thenAccept(
            res -> {
              System.out.println(res); //res contient la deuxième valeur de retour "java1" de thenApply et est sortie vers la console.
            });

//Sortie de la console
// java1

La valeur de thenApply peut être transmise au thenApply suivant.

puis Accepter


    CompletableFuture<String> future1 =
        CompletableFuture.supplyAsync(
            () -> {
              //Processus chronophage
              try {
                Thread.sleep(1000);
              } catch (InterruptedException e) {
                e.printStackTrace();
              }
              return "java1";
            });

//puis Accepter
    future1.thenAccept(
        res -> {
          System.out.println(res); // return res;Ne peut pas être passé à la méthode suivante
        });

//Sortie de la console
// java1

Vous ne pouvez pas écrire return dans la méthode thenAccept ().

La raison peut être comprise en regardant à nouveau le document officiel.

// thenApply
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)

// thenAccept
public CompletableFuture <Void> thenAccept(Consumer<? super T> action)

ThenAccept dit Void dans la valeur de retour, donc vous ne pouvez pas le remettre la prochaine fois, je vois.

Qu'est-ce que ThenCombine?

Renvoie un nouveau CompletionStage qui sera exécuté lorsque ** cette étape ** et ** les autres étapes spécifiées ** se sont terminées avec succès [À propos de la classe CompletableFuture --then Combine](https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/CompletableFuture.html#thenCombine-java.util.concurrent.CompletionStage -java.util.function.BiFunction-)

↓ Si vous interprétez la phrase ci-dessus pour pouvoir la comprendre, ... ** Cette étape = future2 ** Quand ** Autres étapes spécifiées = future3 ** Lorsque les deux ** Nouveau CompletionStage à exécuter = (String s1, String s2) -> s1 +" "+ s2 ** Retour


    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(
            () -> {
              //Processus chronophage
              try{
                Thread.sleep(1000);
              } catch (InterruptedException e){
                e.printStackTrace();
              }
              return "java1";
            }
    );

    CompletableFuture<String> future2 = future1.thenApply(
            s -> {
              //Processus chronophage
              try{
                Thread.sleep(1000);
              } catch (InterruptedException e){
                e.printStackTrace();
              }
              return "java2";
            }
    );

    CompletableFuture<String> future3 = future1.thenApply(
            s -> {
              //Processus chronophage
              try{
                Thread.sleep(1000);
              } catch (InterruptedException e){
                e.printStackTrace();
              }
              return "java3";
            }
    );

    //Dans thenCombine, future2 et le premier argument(future3)Lorsque les deux sont terminés normalement
    // (String s1, String s2) -> s1 + " " +Lancer s2
    future2.thenCombine(future3, (String s1, String s2) -> s1 + " " + s2)
            .thenAccept(System.out::println);

//Sortie de la console
// java2 java3

Différence entre thenApply et thenApplyAsync

Certaines méthodes qui définissent des rappels ont "Async" à la fin du nom de la méthode. "With Async" Exécuté sur le même thread que la tâche précédente Le thread "No Async" est affecté en tant que nouvelle tâche

thenApply ・ ・ ・ Exécuté dans l'ordre futur1 → futur3 → futur2 thenApplyAsync ・ ・ ・ Après l'exécution de future4, future5 et future6 seront exécutées en parallèle.

thenApply

Renvoie un nouveau CompletionStage qui sera exécuté lorsque cette étape se termine avec succès, avec le résultat de cette étape défini comme argument de la fonction spécifiée. thenApply

Avec le code ci-dessous Exécuté dans l'ordre futur1 → futur3 → futur2


    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(
            () -> {
              //Processus chronophage
              try{
                Thread.sleep(1000);
              } catch (InterruptedException e){
                e.printStackTrace();
              }
              return "java1";
            }
    );

    CompletableFuture<String> future2 = future1.thenApply(
            s -> {
              //Processus chronophage
              try{
                Thread.sleep(1000);
              } catch (InterruptedException e){
                e.printStackTrace();
              }
              return "java2";
            }
    );

    CompletableFuture<String> future3 = future1.thenApply(
            s -> {
              //Processus chronophage
              try{
                Thread.sleep(1000);
              } catch (InterruptedException e){
                e.printStackTrace();
              }
              return "java3";
            }
    );

    //Exécuté dans l'ordre futur1 → futur3 → futur2
    future2.thenCombine(future3, (String s1, String s2) -> s1 + " " + s2)
            .thenAccept(System.out::println);

//Sortie de la console
// java2 java3

thenApplyAsync

Lorsque cette étape se termine avec succès, elle définit le résultat de cette étape comme argument de la fonction spécifiée et renvoie un nouveau CompletionStage qui sera exécuté à l'aide de la fonction d'exécution asynchrone par défaut de l'étape. thenApplyAsync

Si tu l'interprètes à ta manière ** Lorsque cette étape (future 4) ** se termine avec succès Le résultat de cette étape Vers la fonction spécifiée () ** Défini sur argument (s dans l'expression lambda) ** et défini Utilisation de la fonctionnalité d'exécution asynchrone par défaut de cette étape ** Exécuté (contenu de l'expression lambda) ** Renvoie un nouveau CompletionStage.

Avec le code ci-dessous Après l'exécution de future4, future5 et future6 seront exécutées en parallèle

      CompletableFuture<String> future4 =
              CompletableFuture.supplyAsync(
                      () -> {
                          //Processus chronophage
                          try {
                              Thread.sleep(1000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          return "java4";
                      });

      CompletableFuture<String> future5 =
              future4.thenApplyAsync(
                      s -> {
                          //Processus chronophage
                          try {
                              Thread.sleep(1000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          return "java5";
                      });

      CompletableFuture<String> future6 =
              future4.thenApplyAsync(
                      s -> {
                          //Processus chronophage
                          try {
                              Thread.sleep(1000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          return "java6";
                      });


      //Après l'exécution de future4, future5 et future6 seront exécutées en parallèle
      future5
              .thenCombine(future6, (String s1, String s2) -> s1 + " " + s2)
              .thenAccept(System.out::println);

//Sortie de la console
// java5 java6

Traitement complet des erreurs futures

Si le traitement asynchrone (supplyAsync) échoue avec une exception, le rappel spécifié dans la méthode thenApply ou thenAccept n'est pas appelé. Dans ce cas, utilisez la méthode whenComplete () ou exceptionally () pour la gestion.

whenComplete

exceptionally

Différence entre puis Compose et Apply

Si vous lisez ceci, vous utilisez généralement thenApply

thenCompose Renvoie un nouveau CompletionStage qui sera exécuté lorsque cette étape se termine avec succès, avec ** cette étape définie sur l'argument ** de la fonction spécifiée.

thenApply Renvoie un nouveau CompletionStage qui sera exécuté lorsque cette étape se termine avec succès, avec ** le résultat de cette étape défini dans l'argument ** de la fonction spécifiée.

public <U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)

public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)

Je ne peux pas faire la différence même si je lis le document officiel ...

J'étudie Completable Future. Confondu avec puis Appliquer puis Rédiger. Post-scriptum: Et j'ai beaucoup appris de M. Uragami! (∩´∀ `) ∩Pourquoi "L'une des utilisations de thenCompose est que j'ai déjà une API qui renvoie un CompletableFuture, et j'ai pensé qu'il serait temps de le combiner."

Veuillez vous référer à cet article ThenCompose si vous avez déjà une API qui renvoie un CompletableFuture Lors de la création d'un nouveau, puis Comme vous pouvez le voir, j'ai à peu près compris que les bases devraient être d'utiliser thenApply.

Résumé

Je ne savais pas comment utiliser la méthode thenApply et quand elle a été exécutée, donc je suis content d'avoir profité de cette occasion pour le savoir.

Recommended Posts

Je ne comprends pas même si je lis le document officiel de CompletableFuture, donc je comprends la recette inversée Java d'une seule main
Je ne peux pas saisir le japonais avec le code VS (Visual Studio Code) d'Ubuntu 18.04.5! ?? Si vous souhaitez télécharger VS Code sur Ubuntu, rendez-vous sur le site officiel! !!
Je n'ai pas vraiment compris le comportement de Java Scanner et .nextLine ()
Depuis que j'ai réussi l'Oracle Java Bronze, j'ai résumé les grandes lignes du test.