Java 8: boucle FOR parallèle

J’ai entendu dire que Java 8 fournit de nombreux utilitaires concernant l’informatique concurrente. Par conséquent, je me demande quelle est la manière la plus simple de paralléliser la boucle donnée?

public static void main(Ssortingng[] args) { Set servers = getServers(); Map serverData = new ConcurrentHashMap(); for (Server server : servers) { String serverId = server.getIdentifier(); String data = server.fetchData(); serverData.put(serverId, data); } } 

Lisez sur les ruisseaux , ils sont tous la nouvelle fureur.

Portez une attention particulière au peu de parallélisme:

“Les éléments de traitement avec une boucle for explicite sont insortingnsèquement sériels. Les stream facilitent une exécution parallèle en recadrant le calcul comme un pipeline d’opérations agrégées, plutôt que comme des opérations impératives sur chaque élément. Toutes les opérations de stream peuvent s’exécuter en série ou en parallèle. ”

Donc, pour résumer, il n’y a pas de boucles parallèles, elles sont insortingnsèquement sérielles. Les stream peuvent cependant faire le travail. Regardez le code suivant:

  Set servers = getServers(); Map serverData = new ConcurrentHashMap<>(); servers.parallelStream().forEach((server) -> { serverData.put(server.getIdentifier(), server.fetchData()); }); 

Ce serait utiliser un Stream :

 servers.parallelStream().forEach(server -> { serverData.put(server.getIdentifier(), server.fetchData()); }); 

Je soupçonne qu’un Collector peut être utilisé plus efficacement ici, puisque vous utilisez une collection concurrente.

Une solution plus élégante ou fonctionnelle consiste simplement à utiliser la fonction Collectors toMap ou toConcurrentMap, qui évite de conserver une autre variable avec état pour ConcurrentHashMap, comme suit:

 final Set servers = getServers(); Map serverData = servers.parallelStream().collect( toConcurrentMap(Server::getIdentifier, Server::fetchData)); 

Note: 1. Ces interfaces fonctionnelles ( Server::getIdentifier or Server::fetchData ) n’autorisent pas les exceptions de jet contrôlé ici, 2. Pour tirer pleinement parti des stream parallèles, le nombre de serveurs serait important et il n’y a pas de I / O impliqué, traitement de données pur dans ces fonctions ( getIdentifier, fetchData )

Reportez-vous à javadoc Collectors à l’ adresse http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toConcurrentMap

en utilisant mon Parallel.For, votre code pourrait ressembler à ceci,

 public staic void main(Ssortingng[] args) { Set servers = getServers(); Map serverData = new ConcurrentHashMap<>(); Parallel.ForEach(servers, new LoopBody() { public void run(Server server) { Ssortingng serverId = server.getIdentifier(); Ssortingng data = server.fetchData(); serverData.put(serverId, data); } }); }