ForkJoinTask的理解
ForkJoinTask understanding
在 subtask.fork() returns 一个 ForkJoinTask<Int>
对象之后会发生什么?此后多次调用 compute() 方法,但从何处以及如何调用?
我是 Java 的新手,我正在尝试学习 fork/join 框架的概念。我在网上看到了下面的代码。我在阅读 Java API 后知道 subtask.fork()
returns 是 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
您需要调用 invokeAll 以便将您的工作分成两部分而不是手动进行,然后将创建 2 个新线程来 'compute' 您的结果,然后如果它不够小则创建 2 个新线程线程等等..,
您无法预测线程的执行顺序,因此每次您 运行 此代码时消息顺序都会有所不同。
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);
invokeAll(new MyRecursiveAction(this.workLoad / 2), new MyRecursiveAction(this.workLoad / 2));
} else {
System.out.println("Doing workLoad myself: " + this.workLoad);
}
}
}
在 subtask.fork() returns 一个 ForkJoinTask<Int>
对象之后会发生什么?此后多次调用 compute() 方法,但从何处以及如何调用?
我是 Java 的新手,我正在尝试学习 fork/join 框架的概念。我在网上看到了下面的代码。我在阅读 Java API 后知道 subtask.fork()
returns 是 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
您需要调用 invokeAll 以便将您的工作分成两部分而不是手动进行,然后将创建 2 个新线程来 'compute' 您的结果,然后如果它不够小则创建 2 个新线程线程等等..,
您无法预测线程的执行顺序,因此每次您 运行 此代码时消息顺序都会有所不同。
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);
invokeAll(new MyRecursiveAction(this.workLoad / 2), new MyRecursiveAction(this.workLoad / 2));
} else {
System.out.println("Doing workLoad myself: " + this.workLoad);
}
}
}