情况是,应用程序有时会无限期挂起。
似乎该错误位于以下代码段中:
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的值时,未检测到任何问题。 最佳答案
在parallelism = N
解决问题的地方设置N > 1
。
奇怪的是,但似乎ForkJoinPool
中存在一些类似于here的错误。