Java >> Java tutorial >  >> Java

Hvornår skal vi kalde join() efter ForkJoinTask.invokeAll()

API'et siger:"Metode invokeAll (tilgængelig i flere versioner) udfører den mest almindelige form for parallel påkald:Fordeling af et sæt opgaver og sammenføjning af dem alle."

Så min antagelse er, hvis jeg bruger invokeAll() , jeg behøver ikke længere bruge fork() eller join() metoder. Det ved jeg også generelt, join() kaldes kun, hvis opgaven returnerer en værdi:en underklasse af:RecursiveTask og bruges ikke, hvis opgaven ikke returnerer en værdi:underklasse af:RecursiveAction .

Jeg stødte på denne tutorial, som har kaldt ForkJoinTask.join() efter det kaldes:invokeAll() :

https://www.baeldung.com/java-fork-join

@Override
    protected Integer compute() {
        if (arr.length > THRESHOLD) {
            return ForkJoinTask.invokeAll(createSubtasks())
              .stream()
              .mapToInt(ForkJoinTask::join) // join() is called
              .sum();
        } else {
            return processing(arr);
        }
    }

Også dette indlæg, som har brugt join() efter at have ringet til invokeAll() :

Hvorfor skal vi kalde join after invokeAll-metoden?

invokeAll(subTask1, subTask2);

return subTask1.join() + subTask2.join();

Samtidig kiggede jeg på mange andre eksempler for invokeAll() og der er INGEN join() efter det opkald.

1) Er der nogen regel om, hvornår vi skal eller ikke skal bruge join() efter invokeAll() ?

2) invokeAll() kommer i tre forskellige signaturer, er dette afhængigt af signaturen på metoden til at beslutte om der skal bruges join() eller ej?

3) På samme note læste jeg også dette i API'et:

“Method invoke() er semantisk ækvivalent med fork(); join(), men forsøger altid at begynde udførelse i den aktuelle tråd."

Siger det at invoke() er lig med fork() plus join() ?

Svar

  1. Kald join(), når du har brug for resultaterne af beregningen. Der er ingen regler for hvornår. Hvis du har andet arbejde at udføre, kan du gøre det, hvis du ikke har andet arbejde at udføre, og du har brug for resultaterne fra beregningen, ring join()

  2. Signaturerne afspejler de forskellige måder at levere opgaverne på. Med en kommer de fra en samling, med en anden kommer de fra varargs eller et array, med den tredje angiver du to som argumenter. Ellers er der ingen forskel på dem. Brug den, der er mest praktisk.

  3. gaffel(); join() er asynkron, arbejdet med gaffel er i en anden tråd, og den aktuelle tråd venter på, at arbejdet er færdigt, når join kaldes. invoke() gør det samme arbejde, men i den aktuelle tråd.


Java tag