1

我从互联网上下载了一些现有的代码。我只做了一些修改就运行了它。在一种情况下,我没有得到我想要的东西。这是代码 -

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

我也期待下面一行 - “Done it ya”..

4

2 回答 2

1

使工作负载静态和易变:

private static volatile long workload = 0;

松开 this.workload 只是工作量。将 if 语句更改为:

if(workload > 0) {

然后您将进入“完成它”。

于 2017-06-02T21:22:41.080 回答
1

我找到了最后一行没有打印的原因。这是因为 fork 以异步方式工作。所以它完全是一个不同的线程,它会休眠一段时间。在异步编程中,除非我们通过代码添加一些构造,否则主线程无需等待响应返回。在这种情况下,当线程在 1 秒后唤醒时,主线程已经结束。

要强制主线程等待其他线程的执行,我们需要使用 JOIN。

ForkJoinTask.join():此方法阻塞,直到计算结果完成。

所以如果我添加以下块

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

主线程等待,我们在控制台上打印所有预期的行。

于 2017-06-13T08:58:19.633 回答