Combien de threads sont générés dans parallelStream en Java 8?

dans JDK8, combien de threads sont générés lorsque j'utilise parallelStream? Par exemple, dans le code:

list.parallelStream().forEach(/** Do Something */);

si cette liste contient 100000 éléments, combien de threads seront générés?

Aussi, ne chacun des threads obtenir le même nombre d'éléments à travailler sur ou est-il soumis au hasard?

40
demandé sur Umberto Raimondi 2015-06-12 14:54:50

2 réponses

l'implémentation de l'Oracle[1] de parallel stream utilise le thread courant et en plus de cela, si nécessaire, les threads qui composent le pool de jointure fork par défaut ForkJoinPool.commonPool(), qui a une taille par défaut égale à un de moins que le nombre de cœurs de votre CPU.

par défaut la taille de la piscine commune peut être changé avec cette propriété:

-Djava.util.concurrent.ForkJoinPool.common.parallelism=8

Alternativement, vous pouvez utiliser votre propre piscine:

ForkJoinPool myPool = new ForkJoinPool(8);
myPool.submit(() ->
    list.parallelStream().forEach(/* Do Something */);
).get();

en ce qui concerne la commande, les travaux seront exécutés comme suit: dès qu'un thread est disponible, dans aucun ordre particulier.

comme @Holger l'a souligné à juste titre, il s'agit d'un détail spécifique à l'implémentation (avec juste une référence vague au bas d'un document), les deux approches fonctionneront sur la JVM D'Oracle mais ne sont certainement pas garantis de fonctionner sur les JVM d'autres vendeurs, la propriété ne pourrait pas exister dans une implémentation non-Oracle et Streams ne pourrait même pas utiliser un ForkJoinPool rendu interne l'alternative basée sur le le comportement de ForkJoinTask.fork totalement inutile (voir ici pour plus de détails).

41
répondu Umberto Raimondi 2018-09-12 08:52:04

alors que @uraimo est correct, la réponse dépend exactement de ce que "faire quelque chose" fait. Parallèle.l'API streams utilise la classe CountedCompleter qui a quelques problèmes intéressants. Puisque le cadre F / J n'utilise pas d'objet séparé pour contenir les résultats, de longues chaînes peuvent aboutir à un OOME. Aussi ces longues chaînes peuvent parfois causer un débordement de pile. La réponse à ces problèmes est l'utilisation de la technique Paraquentielle comme je l'ai souligné dans cet article.

le un autre problème est la création excessive de fil lors de l'utilisation de forEach parallèle imbriqué.

3
répondu edharned 2015-06-12 14:33:48