java.util.concurrent之ForkJoin

来源:互联网 发布:淘宝店怎么提升销量 编辑:程序博客网 时间:2024/05/01 13:54

1.关于ForkJoin的基础知识理解:

http://tutorials.jenkov.com/java-util-concurrent/java-fork-and-join-forkjoinpool.html


2.个人理解:

public class Main {    public static void main(String[] args) throws InterruptedException {        MyRecursiveAction myRecursiveAction = new MyRecursiveAction(24);//MyRecursiveAction类的实现在上面的URL中        myRecursiveAction.fork();TimeUnit.SECONDS.sleep(10);//这个睡眠是为了观察action执行compute的时机        myRecursiveAction.join();    }}

2-1. fork: 

myRecursiveAction.fork();

按照fork join的模型,大任务首先要分解成小任务,当执行myRecursiveAction.fork()时,会创建worker线程:ForkJoinWorkerThread,这个worker线程就会执行提交的任务。但是分解任务的方法不是自动的,需要代码处理,如下:

@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);        }    }
这个compute方法就是要执行的具体任务,但是在分解任务中,这个本来要执行的具体任务变成了执行分解的任务。


2-2. join:

myRecursiveAction.join();
这个方法等待所有的任务执行完成之后,但是要注意的是,当fork的compute方法执行任务分解时,可能需要等待子任务(就是被分解之后的任务)完成,这时需要在compute中调用join方法,否则最外层调用的join方法返回时,完成的只是部分任务。(参照上面的URL里面的RecursiveTask使用方法)。

2-3. 使用时注意事项:

注意deadlock,如在compute中分解任务task->subtask,然后对subtask继续fork,再对subtask执行join方法,因为该worker会等待join方法完成,但是subtask的fork方法又在等待该worker线程的释放,此时可能发生deadlock。(这个场景并没有实际验证过,仅仅是猜测。)


0 0