ForkJoin框架(一):ForkJoin框架概述

1. ForkJoin简述

JAVA 1.7引入了ForkJoin框架,该框架由Java大神Doug Lea所写,它是一个并发执行任务的框架。

Doug Lea关于ForkJoin的论文中给出了这样一段伪代码,不防拿来学习:

Result solve(Problem problem)
  if (problem is small)
    directly solve problem
  else
    split problem into independent parts
    fork new subtasks to solve each part
    join all subtasks
    compose result from subresults

通过这段代码,可以了解到ForkJoin的基本思想,当任务足够小的时候直接解决它,否则将任务分割成可以独立解决的部分,小的任务解决后再将它们合并,得到大的任务结果。看下示例图,更加清晰的理解它:

这里写图片描述

任务分割成任务1和任务2,任务1继续分割成任务1.1和任务1.2,任务2继续分割成任务2.1和任务2.2,此时任务1.1、1.2、2.1、2.2都足够小了,不必继续分割,可以直接解决掉。任务1.1和1.2完成后得到任务1的结果,任务2.1和2.2完成后得到任务2的结果。最终将任务1和任务2的结果归并成任务的结果,本次forkjoin结束。

ForkJoin框架主要由ForkJoinTaskForkJoinWorkerThreadForkJoinPool等类组成,接下来的几篇文章也将围绕这几个类源码进行详细介绍。

2. ForkJoinTask

该类是ForkJoinPool执行的任务,要使用ForkJoin框架,必须创建ForkJoinTask任务。该类提供了将任务分割成子任务的方法fork、等待子任务完成的方法join,通常情况下,我们将一个大的任务fork成两个子任务,再通过join等待子任务完成。

ForkJoinTask是一个抽象类,它有两个子类:RecursiveTask和RecursiveAction,这两个类也是抽象类,其中RecursiveTask是有返回值的任务,RecursiveAction是没有返回值的任务。Recursive是递归的意思,字面意思也可以看出这些任务是可以分割成子任务递归解决的。

实际使用中根据任务是否有返回值,继承RecursiveTask或RecursiveAction,作为真正执行的任务,看下这几个类的类图:

这里写图片描述

ForkJoinTask实现了Future接口,说明它是一个可以异步获取结果的任务,同时该任务实现了序列化接口。

3. ForkJoinWorkerThread和工作窃取算法

该类是执行ForkJoinTask的线程,ForkJoin框架使用的线程维护了一个双端队列,并实现了工作窃取(work-stealing)算法来提高并发的效率。所谓work-stealing算法,指的是线程在完成本线程维护队列中的任务后,可以从其他线程维护的队列中窃取任务来执行,与其说窃取,不如说是帮助其他线程干活。

线程每次从所维护队列的头部取任务执行,当队列中没有任务可执行时,该线程会去其他线程维护队列的尾部窃取任务执行。换句话说,对于本线程维护的队列,任务执行的顺序是LIFO(后进先出),窃取其他线程队列任务的执行顺序是FIFO(先进先出)。看下工作窃取示意图:

这里写图片描述

本线程维护的双端队列,任务的出入队都是通过队首进行的,Thread_1在本队列的队首取任务执行,Thread_2维护的队列为空,此时它不会闲着,而是去Thread_1维护的队列队尾窃取任务来执行,通过示意图可以很清楚的了解其工作流程。这种设计的好处是明显提高了并发执行效率,本线程在队首取任务执行,其他线程窃取的时候在队尾取任务,当队列中只有一个任务的时候才会去争夺锁,其他情况下都不需要争夺锁。

4. ForkJoinPool

ForkJoinPool是执行ForkJoinTask的线程池,它在内部维护了一个ForkJoinThread数组,这些线程就是ForkJoinPool管理的线程。类似于ThreadPoolExecutor,我们将任务提交到ForkJoinPool之后,它维护的线程就会执行我们提交的任务。不同的是,ForkJoinPool会通过工作窃取算法,让线程在完成本身任务之后帮其他线程执行任务, 这个调度是ForkJoinPool的核心功能。

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值