【问题标题】:java parallel stream is using same workerjava并行流正在使用相同的工作人员
【发布时间】:2021-05-25 20:32:54
【问题描述】:

这是我的代码:

    list.stream()
        .parallel()
        .map(cpcP -> this.myDao.myOperation(cip, cpcP))
        .collect(Collectors.toList());

myOperation里面我写了一个日志:

log.debug("{} -> {}", Thread.currentThread().getName(), ...);

我正在获取这些日志:

ForkJoinPool.commonPool-worker-3 -> ...
ForkJoinPool.commonPool-worker-3 -> ...
ForkJoinPool.commonPool-worker-3 -> ...
ForkJoinPool.commonPool-worker-3 -> ...
ForkJoinPool.commonPool-worker-3 -> ...
ForkJoinPool.commonPool-worker-3 -> ...
ForkJoinPool.commonPool-worker-3 -> ...
ForkJoinPool.commonPool-worker-3 -> ...
...

它似乎总是使用同一个线程。

有什么想法吗?

【问题讨论】:

  • list.parallelStream() 怎么样?
  • 我相信流 api 将“检测”流实际上是否足够大以保证分成多个流,或者可以由单个线程快速完成。不过我不知道标准。
  • @markspace 它不会检测到,但是如果启动线程在其他线程甚至开始工作之前完成了它的工作,那么第一个线程将继续处理另一个块,所以在最极端的情况下它可能会完成所有在其他线程设法做出贡献之前的工作。另一种可能的情况是具有有限并行处理能力的源列表,例如使用LinkedList时。
  • 其他可能:其他工作线程正忙于其他并行操作。
  • 并行流使用ForkJoinPool.common(),因此很可能在您的应用程序中该公共池还有其他用途,而您的操作只能获得一个线程。

标签: java java-stream


【解决方案1】:

除了表明公共线程池可能正忙于并行其他操作的 cmets 之外,还有其他几个原因:

  1. 您将系统属性 java.util.concurrent.ForkJoinPool.common.parallelism 设置为 1,明确将池的并行度限制为 1。

  2. 核心数量非常少(1个或2个),因为公共池使用Runtime.getRuntime().availableProcessors() - 1作为并行度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多