我有一些带有方法process()的对象数组,我想要并行化运行。我想尝试lambdas来实现并行化。所以我尝试了这个:
Arrays.asList(myArrayOfItems).forEach(item->{
System.out.println("processing " + item.getId());
item.process();
});
每个process()调用大约需要2秒钟。而且我注意到“并行化”方法仍然没有加速。似乎所有东西仍在运行序列化。 ID是按顺序打印的(有序),每次打印之间都会有2秒的暂停。
可能我误解了一些事情。使用lambdas并行执行此操作需要什么(希望以非常简洁的方式)?
答案 0 :(得分:2)
Lambdas本身并没有并行执行任何操作。 Stream
能够做到这一点。
查看方法Collection#parallelStream
(documentation):
Arrays.asList(myArrayOfItems).parallelStream().forEach(...);
但请注意,实际并行时无法保证或控制。从其文档:
以此集合作为源,返回可能并行的流。此方法允许 返回顺序流。
原因很简单。你真的需要很多你的集合中的元素(如数百万)进行并行化以实际获得回报(或做其他重要的事情)。并行化引入的开销是巨大。因此,如果它认为它会更快,那么该方法可能会选择使用顺序流。
在考虑使用并行性之前,您应该设置一些基准来测试它是否能够改进。有许多例子,人们只是盲目地使用它而没有注意到它们实际上降低了性能。另请参阅Should I always use a parallel stream when possible?。
您可以使用Stream
(documentation)检查Stream#isParallel
是否并列。
如果直接在流上使用Stream#parallel
(documentation),则会获得并行版本。
答案 1 :(得分:1)
方法Collection.forEach()只是迭代所有元素。它被称为内部迭代,因为它留给了它将迭代的集合如何,但它仍然是对所有元素的迭代。
如果要进行并行处理,则必须:
您可以在此处阅读我的解释的第一部分:https://stackoverflow.com/a/22942829/2886891
答案 2 :(得分:1)
要创建并行流,请在集合
上调用操作.parallelStream
请参阅https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html
Arrays.asList(myArrayOfItems).parallelStream().forEach(item->{
System.out.println("processing " + item.getId());
item.process();
});