【问题标题】:How to limit number of parallel executions in ParallelStream?如何限制 ParallelStream 中的并行执行次数?
【发布时间】:2022-02-03 10:11:47
【问题描述】:
list.parallelStream().forEach(element -> ...);

现在如何限制并行线程的数量?

过去有一个“hack”来设置系统属性java.util.concurrent.ForkJoinPool.common.parallelism。但这感觉不对,而且它不再起作用了。

您能否建议如何将列表分块分成 4 个部分,然后仅并行运行这 4 个部分?

【问题讨论】:

  • “它不再起作用了”——真的吗?您指的是哪个 Java 版本?
  • Jdk14.也许我做错了,但除此之外,我也不想改变整个应用程序的并行性。但只需限制一个特定的流。
  • 必须是流操作吗?毕竟,你只是在你的例子中使用了forEach,并且从字面上询问“如何将列表分成 4 个部分”,这实际上是一个微不足道的操作。除非您需要特定的 Stream 功能。
  • @Holger 是的,但问题仍然是如何并行执行 4 个划分的列表......有或没有流。
  • int a = 0, e = list.size(), c = e >>> 1, b = c >>> 1, d = e - b; executorService.invokeAll(Arrays.asList( Executors.callable(() -> list.subList(a, b) .forEach(action)), Executors.callable(() -> list.subList(b, c).forEach(action)), Executors.callable(() -> list.subList(c, d).forEach(action)), Executors.callable(() -> list.subList(d, e).forEach(action)) ));

标签: java multithreading java-stream


【解决方案1】:

我相信您宁愿限制正在执行的并发任务的数量,因此我认为这里没有必要使用并行流,只要 Java 并发包中有一个简单的解决方案即可。改用带有四个固定线程池的ExecutorService

Collection<Callable<Void>> = ...
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.invokeAll(callables);

如果您确实希望在并行流中使用自定义线程池,请参考以下问题:Custom thread pool in Java 8 parallel stream

【讨论】:

  • Callable&lt;Void&gt; 中必须使用return null,这很丑陋。但除此之外,它还有效!
  • @membersound 使用Executors.callable(() -&gt; …)
  • @Holger:那可能是缺失的部分,很好!
【解决方案2】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 2017-10-22
    • 1970-01-01
    相关资源
    最近更新 更多