2017-04-06 4 views
6

En supposant que j'ai une configuration ForkJoinPool avec degré de n parallélisme, et que j'appelle un calcul parallèle comme celui-ci:ForkJoinPool et Future.get

workpool.submit(
      () -> { 
        objects.values().parallelStream().forEach(obj -> { 
         obj.foo(); 
        }); 
       }); 

Je le fais pour faire en sorte que les fils pondus on crée dans le pool de travail (j'ai différents composants du système qui doivent être isolés). Maintenant, supposons que le fil dans lequel on l'appelle, est en cours d'exécution aussi à l'intérieur de cette workpool, et je fais:

Future<?> wait = workpool.submit(
      () -> { 
        objects.values().parallelStream().forEach(obj -> { 
         obj.foo(); 
        }); 
       }); 
wait.get() 

1) Suis-je bloque un fil dans le ForkJoinPool? Si je devais avoir n threads tous bloquer sur les futurs, tout en essayant de planifier une tâche dans le workpool, cela conduirait à l'impasse? Il n'est pas clair pour moi si le "degré maximal de parallélisme" dans le ForkJoinPool signifie que (s'il y a n tâches non bloquées), il y aura toujours n threads en cours d'exécution, ou s'il y a un nombre fixe de threads, il y a des blocages Que dois-je faire si j'utilise wait.join() au lieu de wait.join (je n'ai pas besoin d'exceptions vérifiées car toute exception lancée dans ce code génèrera déjà une exception runtime.) Si je comprends bien, join() permettra aux threads d'exécuter des tâches en file d'attente en attente)

2) suis-je reçois toujours le bénéfice de la lumière poids forkjoin tâches du flux parallèle si je suis en train de créer un « emballage » runnable classe en faisant() -> {}

3) y at-il inconvénient/à l'envers de l'utiliser à la place (en supposant que le .join() effectivement mettre en œuvre le comportement de vol de travail que je pense qu'il fait):

 CompletableFuture.supplyAsync(this::mylambdafunction, workpool) 
      .thenAccept(this::mynextfunction); 

Répondre

1

Réponse au point 1: Il est difficile de savoir si votre code va bloquer sans voir les implémentations de méthodes réelles. Une approche pour traiter le code de blocage consiste à augmenter le nombre de threads dans le pool de thread fork. Normalement, le nombre de threads dans un thread forkjoin est n + 1 pour les tâches de calcul intensif où n = nombre de processeurs. Ou si vous avez un blocage d'E/S, vous pouvez utiliser un ManagedBlocker.

Réponse au point 2: Oui

Réponse du point 3: L'avantage évident à votre code completableFuture est que le thenAccept est non blocage. Ainsi, le contrôle passera immédiatement votre bloc CompletableFuture à l'instruction suivante sans attendre alors que dans le code précédent que vous avez écrit avec un pool ForkJoin, wait.get() bloquera jusqu'à ce que vous obteniez une réponse et ne se poursuivra pas avant.