问题描述
问:当直接调用扩展RecursiveAction / Task的“ X”类中的compute()方法时会发生什么?
无需显式调用ForkJoinPool ,如下所示:
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<?> task = new X(...);
pool.invoke(task);
// X extends RecursiveAction/Task<V>,which also means it is a subclass of ForkJoinTask.
X x = new X(...);
x.compute();
在类X内调用fork()/ invokeAll()方法(不存在明确的ExecutorService)会发生什么?
我的假设是,当扩展类X内的fork()或invoke()方法被调用时,如果没有池,新任务将自动提交给 ForkJoinPool.commonPool()被明确指定。但是我找不到任何指定此行为的文档。
(来自oracle文档的引用可能是相对的)
“主” ForkJoinTask在明确提交后开始执行 到ForkJoinPool,或者,如果尚未参与ForkJoin 计算,通过fork()在ForkJoinPool.commonPool()中开始, invoke()或相关方法。
任何信息或关键字都会受到赞赏。
代码段(请注意“ othertask.fork()”):
class X extends RecursiveTask<Double>{
private Double[] numbersToBeOperated;
private int start;
private int end;
public X(Double numbersToBeOperated,int start,int end){
// define the fields,i.e.,this.* = *;
}
@Override
protected Double compute(){
if(taskDividedToBaseCase){
// do works
} else {
int middle = start + ((end - start) / 2);
RecursiveTask<Double> otherTask = new X(numbersToBeOperated,start,middle);
otherTask.fork(); // what happens here,when compute() is directly called?
return new X(numbersToBeOperated,middle,end).compute() + otherTask.join();
// or invokeAll(new X(...),new X(...)); if RecursiveAction
}
}
}
// then instantiate X and call X.compute() directly.
解决方法
引用java.util.concurrent.ForkJoinTask<V>.fork()
:
安排在当前任务正在运行的池中异步执行此任务(如果适用),或使用 如果不是inForkJoinPool(),则为ForkJoinPool.commonPool()。
它确实转到commonPool()。
还要感谢@Holger指向本文档。