Java 8:并行FOR循环

我听说Java 8提供了很多有关并发计算的实用程序。 所以我想知道什么是最简单的方法来并行给定的循环?

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

阅读stream ,他们都是新的愤怒。

要特别注意平行度的一点:

“使用显式for循环处理元素本质上是串行的,stream通过将计算重新定义为聚合操作的stream水线而不是作为每个单独元素上的命令式操作来促进并行执行,所有stream操作可以以串行或并行方式执行。 “

所以要回顾一下,没有平行的循环,它们本质上是连续的。 stream然而可以做这项工作。 看看下面的代码:

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

这将使用一个Stream

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

我怀疑Collector可以在这里使用更大的效果,因为你使用并发collections。

更优雅或function性的解决scheme将只使用Collector toMap或toConcurrentMap函数,避免为ConcurrentHashMap维护另一个有状态variables,如下例所示:

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

注意:1.这些函数接口( Server::getIdentifier or Server::fetchData )不允许在这里抛出检查exception,2.为了获得并行stream的全部好处,服务器的数量将会很大,并且不存在I / O,这些函数纯粹是数据处理( getIdentifier, fetchData

请参阅http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toConcurrentMap上的收集器javadoc

使用我的Parallel.For,你的代码可能如下所示,

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