fork方法提交到workqueue,线程本身也能获取执行,不能说线程本身就不干活了吧?
Topic source这不是添加队列的问题,而是没有让当前线程去执行分裂出的子任务,导致当前线程变成了“监工”。其实问题很简单的,廖老师都把代码贴出来了,正确和错误的写法你自己换着跑一跑就很容易看出问题来,当然,最好在输出前加上当前线程名~
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种效果是一致的.
其实我这种测试还是很不严谨的,两次fork之后,如果join的时候此时fork出来的子任务刚好都被其他worker窃取了,那么就会出现廖雪峰老师说的那种情况,可以在两次fork之后sleep一段时间,模拟任务被窃取的情况
- 1
放个风筝啦啦啦
廖老师您好, subtask1.fork(); 这个方法是提交到线程自己的workQueue,线程自己也能从workQueue获取task来执行吧?这样的话是不是不能说线程自己不干活?