Discuss / 编程 / fork方法提交到workqueue,线程本身也能获取执行,不能说线程本身就不干活了吧?

fork方法提交到workqueue,线程本身也能获取执行,不能说线程本身就不干活了吧?

Topic source

廖老师您好, subtask1.fork(); 这个方法是提交到线程自己的workQueue,线程自己也能从workQueue获取task来执行吧?这样的话是不是不能说线程自己不干活?

这不是添加队列的问题,而是没有让当前线程去执行分裂出的子任务,导致当前线程变成了“监工”。其实问题很简单的,廖老师都把代码贴出来了,正确和错误的写法你自己换着跑一跑就很容易看出问题来,当然,最好在输出前加上当前线程名~

扁鹊哥

#3 Created at ... [Delete] [Delete and Lock User]
private static class TestTask extends RecursiveAction {    private int taskCnt;    public TestTask(int taskCnt){        this.taskCnt = taskCnt;    }    @Override    protected void compute() {        System.out.println(Thread.currentThread().getName() + " -> " + taskCnt);        if(taskCnt <= 1){            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            return;        }        int mid = taskCnt / 2;        TestTask testTask1 = new TestTask(mid);        TestTask testTask2 = new TestTask(mid);        testTask1.fork();        testTask2.compute();        testTask1.join();        testTask2.join();    }}

public static void main(String[] args) throws Exception {    ForkJoinPool forkJoinPool = new ForkJoinPool(4);    TestTask testTask = new TestTask(4);    System.out.println("start...");    long start = System.currentTimeMillis();    ForkJoinTask<Void> task = forkJoinPool.submit(testTask);    task.get(15, TimeUnit.MINUTES);    System.out.println(System.currentTimeMillis() - start);    System.out.println("end!!!");}

1、

invokeAll(testTask1, testTask2);
testTask1.join();
testTask2.join();

2、

testTask1.fork();testTask2.fork();testTask1.join();testTask2.join();

3、

testTask1.fork();testTask2.compute();testTask1.join();

经测试,以上3种效果是一致的.

扁鹊哥

#4 Created at ... [Delete] [Delete and Lock User]

其实我这种测试还是很不严谨的,两次fork之后,如果join的时候此时fork出来的子任务刚好都被其他worker窃取了,那么就会出现廖雪峰老师说的那种情况,可以在两次fork之后sleep一段时间,模拟任务被窃取的情况


  • 1

Reply