Java 8:并行 FOR 循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27558605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8: Parallel FOR loop
提问by Joe Inner
I have heard Java 8 provides a lot of utilities regarding concurrent computing. Therefore I am wondering what is the simplest way to parallelise the given for loop?
我听说 Java 8 提供了很多关于并发计算的实用程序。因此,我想知道并行化给定 for 循环的最简单方法是什么?
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);
}
}
采纳答案by Reinstate Monica
Read up on streams, they're all the new rage.
阅读流,它们都是新的风潮。
Pay especially close attention to the bit about parallelism:
特别注意并行性:
"Processing elements with an explicit for-loop is inherently serial. Streams facilitate parallel execution by reframing the computation as a pipeline of aggregate operations, rather than as imperative operations on each individual element. All streams operations can execute either in serial or in parallel."
“具有显式 for 循环的处理元素本质上是串行的。流通过将计算重新构建为聚合操作的管道,而不是作为对每个单独元素的命令式操作来促进并行执行。所有流操作都可以串行或并行执行。 ”
So to recap, there are no parallel for-loops, they're inherently serial. Streams however can do the job. Take a look at the following code:
所以回顾一下,没有并行的 for 循环,它们本质上是串行的。然而,Streams 可以完成这项工作。看看下面的代码:
Set<Server> servers = getServers();
Map<String, String> serverData = new ConcurrentHashMap<>();
servers.parallelStream().forEach((server) -> {
serverData.put(server.getIdentifier(), server.fetchData());
});
回答by fge
That would be using a Stream
:
那将使用一个Stream
:
servers.parallelStream().forEach(server -> {
serverData.put(server.getIdentifier(), server.fetchData());
});
I suspect a Collector
can be used to greater effect here, since you use a concurrent collection.
我怀疑 aCollector
可以在这里发挥更大的作用,因为您使用并发集合。
回答by zd333
More elegant or functional solution will be just using Collectors toMap or toConcurrentMap function, which avoid maintaining another stateful variable for ConcurrentHashMap, as following example:
更优雅或功能性的解决方案将只使用收集器 toMap 或 toConcurrentMap 函数,避免为 ConcurrentHashMap 维护另一个有状态的变量,如下例:
final Set<Server> servers = getServers();
Map<String, String> serverData = servers.parallelStream().collect(
toConcurrentMap(Server::getIdentifier, Server::fetchData));
Note:
1. Those functional interfaces (Server::getIdentifier or Server::fetchData
) doesn't allow throw checked exception here,
2. To get the full benefits of parallel stream, the number of servers would be large and there is no I/O involved, purely data processing in those functions(getIdentifier, fetchData
)
注意: 1. 那些函数式接口 ( Server::getIdentifier or Server::fetchData
) 不允许在此处抛出检查异常, 2. 为了获得并行流的全部好处,服务器数量会很大,并且不涉及 I/O,其中纯粹是数据处理函数( getIdentifier, fetchData
)
Please refer to Collectors javadoc at http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toConcurrentMap
请参阅http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toConcurrentMap上的收集器 javadoc
回答by Weimin Xiao
using my Parallel.For, your code might look like the following,
使用我的 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);
}
});
}
回答by Contango
Simple example to copy'n'paste (the examples above use the class Server
which is a custom class written by the OP):
复制“n”粘贴的简单示例(上面的示例使用的Server
是由 OP 编写的自定义类):
import java.io.Console;
import java.util.ArrayList;
ArrayList<String> list = new ArrayList<>();
list.add("Item1");
list.add("Item2");
list.parallelStream().forEach((o) -> {
System.out.print(o);
});
Console output. The order could possibly vary as everything executes in parallel:
控制台输出。顺序可能会有所不同,因为一切都是并行执行的:
Item1
Item2
The .parallelStream()
method was introduced in Java v8
. This example was tested with JDK v1.8.0_181
.
该.parallelStream()
方法是在Java v8
. 这个例子是用JDK v1.8.0_181
.