0
votes

Comment attendre que le bloc asynchrone fermé se termine

Je suis un problème avec flux (). foreach code> Il ne finit pas à temps avant que la méthode ne renvoie, voici comment:

Mon entité: P>

public List<Foo> getOrdresListe() {
    Foo[] fooArray = externalServiceOne.getFooList();
    Arrays.stream(fooArray).forEach((f) -> {
        CompletableFuture.supplyAsync(AsyncUtils.supplierWithCustomDependencies(() -> {
            Dob dob = externalServiceTwo.getDeeEntity(f.getA());
            f.setD(dob.getD());
            Efo efo = externalServiceThree.getEeeEntity(f.getA());
            f.setE(efo.getE());
            return f;
        }));
    });
    List<Foo> fooList = Arrays.asList(fooArray);
    return fooList; // when this statement is reached d and e fields are null.
}


0 commentaires

3 Réponses :


1
votes

Pourquoi ne créez-vous pas tout complétableFuture code> S comme une opération intermédiaire et attendez toutes les exécutions ASYNC pour terminer dans le terminal.

Arrays.stream(fooArray).map((f) -> CompletableFuture.supplyAsync(AsyncUtils.supplierWithCustomDependencies(() -> {
                Dob dob = externalServiceTwo.getDeeEntity(f.getA());
                f.setD(dob.getD());
                Efo efo = externalServiceThree.getEeeEntity(f.getA());
                f.setE(efo.getE());
                return f;
            })
    )).forEach(fooCompletableFuture -> {
        try {
            fooCompletableFuture.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    });


2 commentaires

Cela fonctionne mais la performance sage il faut trop de temps!


Eh bien, vous devez en quelque sorte attendre que toutes les exécutions finissent.



1
votes

Vous pouvez simplement vous rappeler les tâches ASYNC et attendre leur achèvement manuellement:

public List<Foo> getOrdresListe() {
    Foo[] fooArray = externalServiceOne.getFooList();

    final List<CompletableFuture<Foo>> futures = new ArrayList<>(); // remember each

    Arrays.stream(fooArray).forEach((f) -> {
        futures.add(CompletableFuture.supplyAsync(
                AsyncUtils.supplierWithCustomDependencies(() -> {
            Dob dob = externalServiceTwo.getDeeEntity(f.getA());
            f.setD(dob.getD());
            Efo efo = externalServiceThree.getEeeEntity(f.getA());
            f.setE(efo.getE());
            return f;
        })));
    });

    for (CompletableFuture<Foo> future : futures) {
        future.join(); // wait for each
    }

    List<Foo> fooList = Arrays.asList(fooArray);
    return fooList;
}


7 commentaires

Cela fonctionne mais la performance sage il faut trop de temps!


@Fourat Votre question est "... Comment attendre que toute exécution asynchrone a fini ..." Et c'est exactement ce que ma réponse fait. Si cela prend trop de temps, c'est parce que vos tâches asynchronisées prennent beaucoup de temps.


Vous avez raison mais votre réponse est équivalente à la gestion du tout sans async et futur. Y a-t-il une autre façon de le rendre plus rapide?


@Fourat c'est faux, ce n'est pas équivalent. D'où obtenez-vous cette conclusion? Toutes les tâches sont ASYNC ici. Veuillez consulter un Guide de TerminableFuture ou toute autre documentation / tutoriel.


Je sais, mais quand j'enregistre le nom du thread actuel, il affiche toujours le même thread logger.info ("FOO:" + F.Getta () + "thread de courant:" + thread.CurrentThread (). GetName (). ); Je suppose que c'est pourquoi il faut autant de temps!


@Fourat c'est vraiment étrange. Il ne devrait pas toujours être le même fil. Il y a forkjoinpool.commonpool () derrière par défaut terminablefuture , qui devrait utiliser plusieurs threads. Pourriez-vous vérifier votre environnement, par exemple. Runtime.GetRuntime ()


Je l'ai réparé, c'était un flux (). Publier . Merci de votre aide.



1
votes

peut essayer quelque chose comme ceci: Envoyez la demande ASYNC et créez la liste des contrats à terme de type FOO , puis à l'aide de Joindre comme terminal comme @boobalan suggéré ; Vous obtenez les résultats de cette façon, vous pouvez attendre toutes les exécutions ASYNC pour la finition avant de retourner le foas. XXX


0 commentaires