web-dev-qa-db-fra.com

collecte à partir d'un flux parallèle dans Java 8

Je veux prendre une entrée et appliquer un flux parallèle à cela, puis je veux une sortie sous forme de liste. L'entrée peut être n'importe quelle liste ou n'importe quelle collection sur laquelle nous pouvons appliquer des flux.

Ma préoccupation ici est que si nous voulons une sortie en tant que carte, nous avons une option de Java est comme

list.parallelStream().collect(Collectors.toConcurrentMap(args))

Mais il n'y a aucune option que je puisse voir pour collecter à partir d'un flux parallèle de manière sécurisée pour les threads afin de fournir la liste en sortie. Je vois une autre option à utiliser

list.parallelStream().collect(Collectors.toCollection(<Concurrent Implementation>))

de cette façon, nous pouvons fournir diverses implémentations simultanées dans la méthode de collecte. Mais je pense que seule l'implémentation de CopyOnWriteArrayList List est présente dans Java.util.concurrent. Nous pourrions utiliser diverses implémentations de files d'attente ici, mais celles-ci ne seront pas comme la liste. Ce que je veux dire ici, c'est que nous pouvons contourner pour obtenir la liste.

Pourriez-vous s'il vous plaît me guider quelle est la meilleure façon si je veux la sortie en tant que liste?

Remarque: Je n'ai trouvé aucun autre message lié à cela, toute référence serait utile.

13
Vipul Goyal

L'objet Collection utilisé pour recevoir les données collectées n'a pas besoin d'être simultané. Vous pouvez lui donner un simple ArrayList.

En effet, la collection de valeurs d'un flux parallèle n'est pas réellement collectée dans un seul objet Collection. Chaque thread collectera ses propres données, puis tous les sous-résultats seront fusionnés en un seul objet Collection final.

Tout cela est bien documenté dans le javadoc Collector , et le Collector est le paramètre que vous donnez à la collect() méthode:

<R,A> R collect(Collector<? super T,A,R> collector)
23
Andreas

But there is no option that I can see to collect from parallel stream in thread safe way to provide list as output. C'est tout à fait faux.

L'intérêt des flux est que vous pouvez utiliser une collection non thread-safe pour obtenir des résultats thread-safe parfaitement valides. Cela est dû à la façon dont les flux sont mis en œuvre (et c'était un élément clé de la conception des flux). Vous pouvez voir qu'un Collector définit une méthode supplier qui à chaque étape créera une nouvelle instance. Ces instances seront fusionnées entre elles.

C'est donc parfaitement sûr pour les threads:

 Stream.of(1,2,3,4).parallel()
          .collect(Collectors.toList());

Puisqu'il y a 4 éléments dans ce flux, il y aura 4 instances de ArrayList créées qui seront fusionnées à la fin en un seul résultat (en supposant au moins 4 cœurs CPU)

De l'autre côté, des méthodes comme toConcurrent génèrent un conteneur de résultat unique et tous les threads y mettront leur résultat.

6
Eugene