Groovy Gpars.withPool线程经过多次迭代后最终停止执行

Groovy Gpars.withPool线程经过多次迭代后最终停止执行,groovy,gpars,Groovy,Gpars,正在尝试使用GPAR执行并发操作 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[For

正在尝试使用GPAR执行并发操作

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的速度进行迭代。

以防万一其他人也有同样的问题。他们的文件说:

因为GParsPool使用Fork/Join池(带有工作窃取),所以线程可能不会应用于等待处理的任务,即使它们看起来是空闲的。使用工作窃取算法,没有事情可做的工作线程可以从其他仍然繁忙的线程窃取任务

如果您使用GParsExecutorsPool,它不使用Fork/Join,那么您将获得您天真地期望的线程分配行为

基于此,我选择使用GParsExecutorsPool。这样,所有线程都会一致地执行,直到整个并行进程结束

GParsExecutorsPool.withPool(6) {
  someList.eachParallel {
    println "${Thread.currentThread}"
  }
}

以防其他人也有同样的问题。他们的文件说:

因为GParsPool使用Fork/Join池(带有工作窃取),所以线程可能不会应用于等待处理的任务,即使它们看起来是空闲的。使用工作窃取算法,没有事情可做的工作线程可以从其他仍然繁忙的线程窃取任务

如果您使用GParsExecutorsPool,它不使用Fork/Join,那么您将获得您天真地期望的线程分配行为

基于此,我选择使用GParsExecutorsPool。这样,所有线程都会一致地执行,直到整个并行进程结束

GParsExecutorsPool.withPool(6) {
  someList.eachParallel {
    println "${Thread.currentThread}"
  }
}

其他线程完成工作了吗?打印了多少行?是的。我很肯定他们不会一意孤行。因为在我的测试中,它们只是在打印。至于有多少次,我相信它能够完成预期的迭代次数,其他线程是否完成了它们的工作?打印了多少行?是的。我很肯定他们不会一意孤行。因为在我的测试中,它们只是打印。至于有多少次,我相信它能够完成预期的迭代次数