ForkJoinTask了解

时间:2016-02-27 23:16:59

标签: java multithreading threadpool fork-join

在subtask.fork()返回ForkJoinTask<Int>个对象后会发生什么?之后多次调用compute()方法但是从哪里以及如何调用?

我是Java的新手,我正在尝试学习fork / join框架的概念。我在网上看到了下面的代码。我知道在阅读Java API后,subtask.fork()返回ForkJoinTask<V>的对象,在这种情况下为ForkJoinTask<Int>。我无法理解的是之后会发生什么?输出表明compute()方法在此之后已被多次调用,但是从哪里以及如何调用?

public class MyRecursiveAction extends RecursiveAction {

    public static void main(String[] args) {
        MyRecursiveAction mra1 = new MyRecursiveAction(100);
        ForkJoinPool fjp1 = new ForkJoinPool();
        fjp1.invoke(mra1);
    }

    private long workLoad = 0;

    public MyRecursiveAction(long workLoad) {
        this.workLoad = workLoad;
    }

    @Override
    protected void compute() {

        //if work is above threshold, break tasks up into smaller tasks
        if(this.workLoad > 16) {
            System.out.println("Splitting workLoad : " + this.workLoad);

            List<MyRecursiveAction> subtasks =
                new ArrayList<MyRecursiveAction>();

            subtasks.addAll(createSubtasks());

            for(RecursiveAction subtask : subtasks){
                subtask.fork();
            }

        } else {
            System.out.println("Doing workLoad myself: " + this.workLoad);
        }
    }

    private List<MyRecursiveAction> createSubtasks() {
        List<MyRecursiveAction> subtasks =
            new ArrayList<MyRecursiveAction>();

        MyRecursiveAction subtask1 = new MyRecursiveAction(this.workLoad / 2);
        MyRecursiveAction subtask2 = new MyRecursiveAction(this.workLoad / 2);

        subtasks.add(subtask1);
        subtasks.add(subtask2);

        return subtasks;
    }

}

输出:

Splitting workLoad : 100
Splitting workLoad : 50
Splitting workLoad : 50
Splitting workLoad : 25
Doing workLoad myself: 12
Doing workLoad myself: 12
Splitting workLoad : 25
Doing workLoad myself: 12
Doing workLoad myself: 12
Splitting workLoad : 25
Doing workLoad myself: 12
Splitting workLoad : 25
Doing workLoad myself: 12
Doing workLoad myself: 12
Doing workLoad myself: 12

1 个答案:

答案 0 :(得分:1)

你需要调用invokeAll,以便将你的工作分成两部分而不是手工完成,然后创建2个新的线程来计算&#39;你的结果,如果它不够小2个新线程等等,

您无法预测线程的执行顺序,因此每次运行此代码时,消息顺序都会有所不同。

CREATE TABLE STUDENT
(sID INTEGER PRIMARY KEY NOT NULL,
sFName VARCHAR(20),
sLName VARCHAR(20));

CREATE TABLE COURSE
(cID VARCHAR(20) PRIMARY KEY NOT NULL,
cName VARCHAR(20),
cr INTEGER);

CREATE TABLE PROF
(pID INTEGER PRIMARY KEY NOT NULL,
pFName VARCHAR(20),
pLName VARCHAR(20));

CREATE TABLE ENROLLED
(sID INTEGER NOT NULL,
cID VARCHAR(20) NOT NULL,
PRIMARY KEY (sID, cID),
FOREIGN KEY (sID) REFERENCES STUDENT,
FOREIGN KEY (cID) REFERENCES COURSE);

CREATE TABLE TEACHING
(pID INTEGER NOT NULL,
cID VARCHAR(20) NOT NULL,
PRIMARY KEY (pID, cID),
FOREIGN KEY (pID) REFERENCES PROF,
FOREIGN KEY (cID) REFERENCES COURSE);

Java doc of ForkJoinTask