Gpars.withPool 线程在多次迭代后最终停止执行
Gpars.withPool threads eventually stops executing after iterating numerous times
正在尝试使用 Gpars 执行并发操作。
Gpars.withPool(6) {
someList.eachParallel {
println "${Thread.currentThread}"
}
}
最初它似乎有效
Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-6,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-5,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-4,5,main]
Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-6,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
但是迭代一段时间后,一些线程停止执行。
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
直到最后我们只剩下一个。
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
知道为什么会这样吗?保持所有线程活动的任何解决方案?
就我而言,可能值得一提的是我们的迭代速度约为 50k-200k。
以防其他人遇到同样的问题。他们的文档说:
Because GParsPool uses a Fork/Join pool (with work stealing), threads may not be applied to a waiting processing task even though they may appear idle. With a work-stealing algorithm, worker threads that run out of things to do can steal tasks from other threads that are still busy.
if you use GParsExecutorsPool , which doesn't use Fork/Join, you get the thread allocation behavior that you would naively expect.
基于此,我选择改用 GParsExecutorsPool。有了这个,所有线程都一致地执行,直到整个 eachParallel 进程结束。
GParsExecutorsPool.withPool(6) {
someList.eachParallel {
println "${Thread.currentThread}"
}
}
正在尝试使用 Gpars 执行并发操作。
Gpars.withPool(6) {
someList.eachParallel {
println "${Thread.currentThread}"
}
}
最初它似乎有效
Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-6,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-5,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-4,5,main]
Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-6,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
但是迭代一段时间后,一些线程停止执行。
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
直到最后我们只剩下一个。
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
Thread[ForkJoinPool-1-worker-2,5,main]
知道为什么会这样吗?保持所有线程活动的任何解决方案?
就我而言,可能值得一提的是我们的迭代速度约为 50k-200k。
以防其他人遇到同样的问题。他们的文档说:
Because GParsPool uses a Fork/Join pool (with work stealing), threads may not be applied to a waiting processing task even though they may appear idle. With a work-stealing algorithm, worker threads that run out of things to do can steal tasks from other threads that are still busy.
if you use GParsExecutorsPool , which doesn't use Fork/Join, you get the thread allocation behavior that you would naively expect.
基于此,我选择改用 GParsExecutorsPool。有了这个,所有线程都一致地执行,直到整个 eachParallel 进程结束。
GParsExecutorsPool.withPool(6) {
someList.eachParallel {
println "${Thread.currentThread}"
}
}