【问题标题】:Fork Join pool hangs分叉加入池挂起
【发布时间】:2018-04-28 13:58:18
【问题描述】:

情况是应用程序不时无限挂起。

似乎该错误位于以下 sn-p 中:

ForkJoinPool pool = new ForkJoinPool(1); // parallelism = 1

List<String> entries = ...;

pool.submit(() -> {

    entries.stream().parallel().forEach(entry -> {
        // An I/O op.
        ...
    });

}).get();

执行代码的线程pool-4-thread-1 冻结在get()

"pool-4-thread-1" #35 prio=5 os_prio=0 tid=0x00002b42e4013800 nid=0xb7d1 in Object.wait() [0x00002b427b72f000]
       java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at java.util.concurrent.ForkJoinTask.externalInterruptibleAwaitDone(ForkJoinTask.java:367)
        - locked <0x00000000e08b68b8> (a java.util.concurrent.ForkJoinTask$AdaptedRunnableAction)
        at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1001)
...other app methods

可以假设传递给submit() 的任务执行时间过长。

但令人惊讶的是,线程转储中没有出现ForkJoinPool-N-worker-N,所以看起来池没有执行任何计算!

这怎么可能?如果池中没有任务执行,为什么pool-4-thread-1线程在get()内部等待?

P.S.我知道不建议在ForkJoinPool执行I/O相关的任务,但还是对问题的根源感兴趣。

更新。parallelism 设置为大于 1 的值时,不会检测到问题。

【问题讨论】:

  • 线程转储还显示了哪些其他线程? .get() 显然还在等待一些计算。
  • @manouti 完整的堆栈跟踪可以在这里找到:paste.ix/QS02o
  • @Ivan 谢谢。似乎给定问题中的问题已经针对我的 JVM 版本解决了。
  • @Aliaxander 可能并非所有情况都已修复,您需要为 OpenJDK 提出一个错误。

标签: java multithreading java-stream fork-join forkjoinpool


【解决方案1】:

设置parallelism = NN &gt; 1 解决了问题。

奇怪的事情,但似乎ForkJoinPool 中存在一些类似于here 所述的错误。

【讨论】:

    猜你喜欢
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 2012-08-31
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多