尝试使用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。
答案 0 :(得分:0)
以防其他人遇到同样的问题。他们的文件说:
由于GParsPool使用Fork / Join池(带有工作窃取),因此线程可能不会应用于等待处理任务,即使它们可能显得空闲。使用工作窃取算法,用尽线索的工作线程可以从仍然忙碌的其他线程中窃取任务。
如果您使用不使用Fork / Join的GParsExecutorsPool,您将获得您天真期望的线程分配行为。
基于此,我选择使用GParsExecutorsPool。这样,所有线程都会一直执行,直到整个eachParallel进程结束。
GParsExecutorsPool.withPool(6) {
someList.eachParallel {
println "${Thread.currentThread}"
}
}