Fork And Join框架初探

首先,关于Fork And Join框架的入门资料我觉得最好的是:
 Java线程(十一):Fork/Join-Java并行计算框架
本文参考了这篇文章
Fork/Join框架的核心类是ForkJoinPool,它能够接收一个ForkJoinTask,并得到计算结果。ForkJoinTask有两个子类,RecursiveTask(有返回值)和RecursiveAction(无返回结果),我们自己定义任务时,只需选择这两个类继承即可。类图如下: 

Fork And Join框架初探_第1张图片


首先咱们说有返回值的
我们的类要继承RecursiveTask
我们知道RecursiveTask是泛型类,如果我们希望最后返回的是一个List
那么我们的类就如下:
public class MyTask extends RecursiveTask>
另外上文中获取结果用的是get,当然我们也可以用join
看看对join的解释
Returns the result of the computation when it is done. This method differs from get() in that abnormal completion results in RuntimeException or Error, not ExecutionException, and that interrupts of the calling thread do not cause the method to abruptly return by throwing InterruptedException.
说实话,没看懂上面的英文。
(我靠,英语烂,怪谁)

看两个方法的说明

Fork And Join框架初探_第2张图片

Fork And Join框架初探_第3张图片

也就是异常的处理上不同么
(感觉还是没有什么大的区别)


再说没有返回值的
以前使用的invokeAll()的方法是同步的,也就是任务提交后,这个方法不会返回直到所有的任务都处理完了。而还有另一种方式,就是使用fork方法,这个是异步的。也就是你提交任务后,fork方法立即返回,可以继续下面的任务。这个线程也会继续运行。
所以说在使用没有返回值的时候
再说明一点
线程是在fork或者invokeAll()时开始的。
join或者get只是阻塞的获取结果。
关于同步异步问题,我曾经犯过一个问题
使用的是没有返回值的RecursiveAction,我想着既然没有返回值,那我就只fork,不用join了

后面当然出问题了,fork是异步的,直接进行下一步,还没处理完呢么。

一个invokeAll等于两边的都fork然后join

// invokeAll(left,right);  
left.fork();
right.fork();
left.join();
right.join();
所以总而言之,如果是同步的使用invokeAll,异步的话,不管有没有返回值都要先fork然后再join。
同样的在创建forkandjoin的时候
        // 1. 创建任务
    	PassengerTask passengerTask = new PassengerTask(list, 0, list.size()-1,circleCount,parseStatus);

        // 2. 创建线程池
        ForkJoinPool forkJoinPool = new ForkJoinPool();

        // 3. 提交任务到线程池
        forkJoinPool.submit(passengerTask);
        
        passengerTask.join();
	list.get(1);
	//....

也得join。
为什么?
同样的,因为:任务还没处理完,你就操作原始数据了。




资料:
 Java线程(十一):Fork/Join-Java并行计算框架
使用Java7提供的Fork/Join框架

你可能感兴趣的:(线程)