Fork/Join是Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。
一、 Fork/Join的运行流程图
二、工作窃取算法
工作窃取算法是指某个线程从其他队列里窃取任务去执行。在处理一个大任务时,将这个大任务分成若干个小任务,放在不同的队列里,如果某个线程执行完自己所属的队列任务时,线程就会空闲。与其空闲,何不去其他线程队列里去任务执行呢。于是这个线程就会去其他线程队列窃取任务执行。这个队列一般选用双端队列,被窃取任务的线程永远从队尾去取,而窃取任务的线程则去队头去窃取任务。
工作窃取算法的优点:充分利用线程进行并行计算,减少了线程间的竞争
工作窃取算法的缺点:在某些情况下还是存在竞争,比如双端队列中只有一个任务。
三、Fork/Join框架的设计
1、分割任务:首先我们需要一个fork类来分割一个大任务,知道子任务足够小
2、执行任务并合并结果:分割的子任务放入到双端队列中,然后几个线程启动分别从双端队列里取任务进行执行。子任务
执行的结果放到都统一放在一个队列里,然后启动一个线程去合并结果。
Fork/Join使用两个类完成以上事情:
①ForkJoinTask:我们要使用Fork/Join,必须先创建一个ForkJoin任务,它提供fork和join方法的操作。通常情况下,我们不需要直接继承ForkJoinTask,而是继承它的子类
a、RecursiveAction:用于没有返回结果的任务
b、RecursiveTask:用于有返回结果的任务
②ForkJoinPool:ForkJoinTask任务必须要由ForkJoinPool来执行
四、Fork/Join框架的应用
使用ForkJoin框架来进行求和
1、首先要如何分割子任务,我们需要设置一个阈值,也就是每个线程求和的数量少于多少开始进行求和,不然就继续分割子任务,假定我们将阈值设为200000。其次因为我们是求和操作,所以需要继承RecursiveTa