我从互联网上下载了一些现有代码。我运行它几乎没有修改。在一个场景中,我没有得到我想要的东西。这是代码 -
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class MyRecursiveAction extends RecursiveAction{
private long workload = 0;
public MyRecursiveAction(long workload) {
this.workload = workload;
}
@Override
protected void compute() {
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 work myself1 " + this.workload);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done it ya " + this.workload);
}
}
private List<MyRecursiveAction> createSubtasks() {
List<MyRecursiveAction> subTasks = new ArrayList<>();
MyRecursiveAction subtask1 = new MyRecursiveAction(this.workload / 2);
MyRecursiveAction subtask2 = new MyRecursiveAction(this.workload / 2);
subTasks.add(subtask1);
subTasks.add(subtask2);
return subTasks;
}
public static void main(String[] args) {
MyRecursiveAction myRecursiveAction = new MyRecursiveAction(24);
ForkJoinPool forkJoinPool = new ForkJoinPool(4);
forkJoinPool.invoke(myRecursiveAction);
}
}
检查以下摘录 -
System.out.println("Doing work myself1 " + this.workload);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done it ya " + this.workload);
我加了1秒的睡眠,然后又打印了另一个声明。但是,如果我运行代码,我就不会看到该语句被打印出来。我不明白为什么。为什么不打印?实际上执行的结果是 -
Splitting workload :: 24
Doing work myself1 12
Doing work myself1 12
我也期待以下一行 - &#34;完成它&#34; ..
答案 0 :(得分:1)
使工作负载静态和易变:
private static volatile long workload = 0;
只为工作负载放松this.workload。 如果声明改为:
if(workload > 0) {
然后你会得到“完成它”。
答案 1 :(得分:0)
我找到了为什么最后一行没有被打印的原因。这是因为fork以异步方式工作。所以它完全是一个不同的线程,睡了一段时间。在异步编程中,除非我们通过代码添加一些结构,否则主线程不需要等待响应返回。在这种情况下,时间线程在1秒后唤醒,主线程已经结束。
要强制主线程等待其他线程的执行,我们需要使用JOIN。
ForkJoinTask.join():此方法将一直阻塞,直到完成计算结果。
所以如果我添加以下块
for(RecursiveAction subtask : subtasks) {
subtask.join();
}
主线程等待,我们得到控制台上打印的所有预期线条。