【问题标题】:Collection iteration with forEach() in multiple threads or with forEach() and lambdas在多个线程中使用 forEach() 或使用 forEach() 和 lambda 进行集合迭代
【发布时间】:2016-04-14 06:28:28
【问题描述】:

假设我有一个包含数千个独立对象的数组。现在我想传递它们中的每一个并执行相同的操作,例如,更改特定字段的值。

乍一看,Java 8 中有多种方法可以完成此类任务,例如:

  1. forEach(); 内部带有 lambda 表达式:
    itemsArr.forEach(item -> item.setValue("test"));
  2. forEach(); 带迭代器。
  3. 将数组分离为多个批次/块,并在单独的线程中处理每个批次。例如:定义 2 个线程,#0 到 999 的元素将在线程 «A» 中执行,其余元素在线程 «B» 中执行。

最终结果应该是:100% 的数组元素都应该被关心。
完成此类任务的最佳方法是什么?

更新: 有一个类似的question,但谈到另一方面,我感兴趣的不是不同类型的循环性能比较(whileforforEach),而是性能比较数组遍历任务中的威胁与 lambdas

【问题讨论】:

  • 如果性能不是什么大问题,那你能解释一下“preferable”是什么意思吗?
  • 拥有一个包含一百万个对象的数组首先是个坏主意。这取决于对象的类型,但我相信您可以找到它的替代方案。然后,如果您需要修改每个单独的值,则别无选择,只能遍历它们中的每一个。然后如何遍历它们取决于您的数据结构
  • @Gaktan,有 数百万个对象 我真的夸大了,事实上有数以千计的对象。我更新了问题以使其更清楚。
  • @MikeB.,有数千而不是数百万,您的问题完全失去了意义,在这么小的样本上使用多线程没有任何好处。
  • @user3707125,我不排除这种情况,当集合也将包含 10K…50K 时。主指针是最好的手动定义几个线程并在多个线程中处理数组或使用 lambdas 在单个线程中执行处理。

标签: java multithreading performance lambda iteration


【解决方案1】:

使用 parallel 流,JVM 将使用多个线程对其进行处理:

Arrays.stream(itemsArr).parallel().forEach(item -> item.setValue("test"));

虽然你似乎有一个集合,而不是一个数组,所以:

itemsArr.parallelStream().forEach(item -> item.setValue("test"));

【讨论】:

  • 谢谢,波西米亚人。这似乎是我正在寻找的东西。还有一个问题,这种方法生成了多少线程?是不是像ForkJoinPool,根据stackoverflow.com/a/21172732/462347,默认情况下与处理器一样少一个线程,由Runtime.getRuntime().availableProcessors()返回。
  • @MikeB.,不要忘记如果作业是从外部提交并且调用者等待作业完成,FJP 也会使用调用者线程来完成其工作。所以在实践中它将等于可用处理器的数量。
  • @TagirValeev,好的。顺便说一句,我在 Java 8 中阅读了许多关于 parallelStream() 的负面反馈,关于它的副作用和陷阱。你在生产中使用它吗?
  • @MikeB.,不,我在生产中很少遇到parallel() 适合的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 2016-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
相关资源
最近更新 更多