我怎么知道 Fork 和 Join 在 Java 中是否有足够的池大小?
How do I know if Fork and Join has enough pool size in Java?
我正在尝试对一些大数据实施分而治之的解决方案。我使用 fork 和 join 将事物分解为线程。但是我有一个关于分叉机制的问题:如果我将我的分而治之条件设置为:
@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 框架是否维护可用线程的池大小?或者我应该将这个条件添加到我的分而治之逻辑中吗?
每个 ForkJoinPool
都有一个已配置的目标 parallelism. This isn’t exactly matching the number of threads, i.e. if a worker thread is going to wait via a ManagedBlocker
, the pool may start even more threads to compensate. The parallelism of the commonPool
默认为“CPU 核心数减一”,因此当将启动非池线程合并为助手时,由此产生的并行性将利用所有 CPU 个内核。
当您提交的作业多于线程时,它们将被排队。排队一些作业可以帮助利用线程,因为并非所有作业都可能 运行 完全相同,因此线程 运行 停止工作可能会从其他线程窃取作业,但过多地拆分工作可能造成不必要的开销。
因此,您可以使用ForkJoinTask.getSurplusQueuedTaskCount()
获取当前挂起作业的数量,这些作业不太可能被其他线程窃取,只有在低于一个小阈值时才会拆分。正如其文档所述:
This value may be useful for heuristic decisions about whether to fork other tasks. In many usages of ForkJoinTasks, at steady state, each worker should aim to maintain a small constant surplus (for example, 3) of tasks, and to process computations locally if this threshold is exceeded.
所以这是决定是否进一步拆分工作的条件。由于此数字反映空闲线程何时窃取您创建的作业,因此当作业具有不同的 CPU 负载时会导致平衡。此外,它以相反的方式工作,如果池是共享的(如公共池)并且线程已经很忙,它们将不会接手你的工作,盈余计数将保持高位,然后你将自动停止拆分。
我正在尝试对一些大数据实施分而治之的解决方案。我使用 fork 和 join 将事物分解为线程。但是我有一个关于分叉机制的问题:如果我将我的分而治之条件设置为:
@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 框架是否维护可用线程的池大小?或者我应该将这个条件添加到我的分而治之逻辑中吗?
每个 ForkJoinPool
都有一个已配置的目标 parallelism. This isn’t exactly matching the number of threads, i.e. if a worker thread is going to wait via a ManagedBlocker
, the pool may start even more threads to compensate. The parallelism of the commonPool
默认为“CPU 核心数减一”,因此当将启动非池线程合并为助手时,由此产生的并行性将利用所有 CPU 个内核。
当您提交的作业多于线程时,它们将被排队。排队一些作业可以帮助利用线程,因为并非所有作业都可能 运行 完全相同,因此线程 运行 停止工作可能会从其他线程窃取作业,但过多地拆分工作可能造成不必要的开销。
因此,您可以使用ForkJoinTask.getSurplusQueuedTaskCount()
获取当前挂起作业的数量,这些作业不太可能被其他线程窃取,只有在低于一个小阈值时才会拆分。正如其文档所述:
This value may be useful for heuristic decisions about whether to fork other tasks. In many usages of ForkJoinTasks, at steady state, each worker should aim to maintain a small constant surplus (for example, 3) of tasks, and to process computations locally if this threshold is exceeded.
所以这是决定是否进一步拆分工作的条件。由于此数字反映空闲线程何时窃取您创建的作业,因此当作业具有不同的 CPU 负载时会导致平衡。此外,它以相反的方式工作,如果池是共享的(如公共池)并且线程已经很忙,它们将不会接手你的工作,盈余计数将保持高位,然后你将自动停止拆分。