ForkJoinFramwork,无需显式ForkJoinPool / ExecutorService

问题描述

问:当直接调用扩展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指向本文档。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...