多线程如何知道Fork和Join在Java中是否有足够的池大小?
我正在尝试对一些大数据实施分而治之的解决方案。我使用fork和join将事物分解成线程。但是,我有一个关于fork机制的问题:如果我将分治条件设置为:
@Override
protected SomeClass compute(){
if (list.size()<LIMIT){
//Do something here
...
}else{
//Divide the list and invoke sub-threads
SomeRecursiveTaskClass subWorker1 = new SomeRecursiveTaskClass(list.subList());
SomeRecursiveTaskClass subWorker2 = new SomeRecursiveTaskClass(list.subList());
invokeAll(subWorker1, subWorker2);
...
}
}
如果没有足够的资源来调用subWorker
(例如池中没有足够的线程),会发生什么情况?Fork/Join框架是否为可用线程维护池大小?或者我应该在分而治之的逻辑中加入这个条件
# 1 楼答案
每个} 等待,那么池可能会启动更多线程来进行补偿。^{} 的并行性默认为“CPU核数减一”,因此当将启动的非池线程合并为辅助线程时,生成的并行性将利用所有CPU核
ForkJoinPool
都有一个配置的目标parallelism。这与线程的数量并不完全匹配,也就是说,如果工作线程将通过^{当提交的作业多于线程时,它们将排队。将几个作业排队有助于利用线程,因为并非所有作业都可以完全同时运行,因此工作不足的线程可能会从其他线程窃取作业,但拆分工作过多可能会产生不必要的开销
因此,您可以使用^{} 获取当前挂起的作业数,这些作业不太可能被其他线程窃取,并且只有在低于一个小阈值时才会被分割。正如其文件所述:
因此,这是决定是否进一步拆分工作的条件。因为这个数字反映了空闲线程窃取创建的作业的时间,所以当作业具有不同的CPU负载时,它将导致平衡。此外,它的工作原理是相反的,如果池是共享的(就像公共池一样),线程已经很忙,它们将不会接收您的作业,剩余计数将保持较高,然后您将自动停止拆分