Fork/Join 框架基本使用和原理

ForkJoin 线程池框架回顾

ForkJoin 框架其实就是一个线程池 ExecutorService 的实现,通过工作窃取(work-stealing)算法,获取其他线程中未完成的任务来执行。

可以充分利用机器的多处理器优势,利用空闲的线程去并行快速完成一个可拆分为小任务的大任务,类似于分治算法。

ForkJoin 的目标,就是利用所有可用的处理能力来提高程序的响应和性能。本文将介绍 ForkJoin 框架,源码剖析。

ForkJoinPool 核心类实现

ForkJoin 框架的核心是 ForkJoinPool 类,基于 AbstractExecutorService 扩展。

ForkJoinPool 中维护了一个队列数组 WorkQueue[],每个 WorkQueue 维护一个 ForkJoinTask 数组和当前工作线程。

ForkJoinPool 实现了工作窃取(work-stealing)算法并执行 ForkJoinTask。

ForkJoinPool,所有线程和 WorkQueue 共享,用于工作窃取、任务状态和工作状态同步。

核心属性介绍

ADD_WORKER: 100000000000000000000000000000000000000000000000 -> 1000 0000 0000 0000,用来配合 ctl 在控制线程数量时使用

ctl: 控制 ForkJoinPool 创建线程数量,(ctl & ADD_WORKER) != 0L 时创建线程,也就是当 ctl 的第 16 位不为 0 时,可以继续创建线程

defaultForkJoinWorkerThreadFactory: 默认线程工厂,默认实现是 DefaultForkJoinWorkerThreadFactory

runState: 全局锁控制,全局运行状态

workQueues: 工作队列数组 WorkQueue[]

config: 记录并行数量和 ForkJoinPool 的模式(异步或同步)

ForkJoinTask
status: 任务的状态,对其他工作线程和 pool 可见,运行正常则 status 为负数,异常情况为正数

WorkQueue
qlock: 并发控制,put 任务时的锁控制

array: 任务数组 ForkJoinTask<?>[]

pool: ForkJoinPool,所有线程和 WorkQueue 共享,用于工作窃取、任务状态和工作状态同步

base: array 数组中取任务的下标

top: array 数组中放置任务的下标

owner: 所属线程,ForkJoin 框架中,只有一个 WorkQueue 是没有 owner 的,其他的均有具体线程 owner。

WorkQueue 内部就是 ForkJoinTask

workQueue: 当前线程的任务队列,与 WorkQueue 的 owner 呼应

ForkJoinTask 是能够在 ForkJoinPool 中执行的任务抽象类,父类是 Future,具体实现类有很多,这里主要关注 RecursiveAction 和 RecursiveTask。

RecursiveAction 是没有返回结果的任务

RecursiveTask 是需要返回结果的任务

只需要实现其 compute()方法,在 compute()中做最小任务控制,任务分解(fork)和结果合并(join)。

ForkJoinWorkerThread

ForkJoinPool 中执行的默认线程是 ForkJoinWorkerThread,由默认工厂产生,可以自己重写要实现的工作线程。同时会将 ForkJoinPool 引用放在每个工作线程中,供工作窃取时使用。

pool: ForkJoinPool,所有线程和 WorkQueue 共享,用于工作窃取、任务状态和工作状态同步

workQueue: 当前线程的任务队列,与 WorkQueue 的 owner 呼应

ForkJoinPool 作为最核心的组件,维护了所有的任务队列 WorkQueues,workQueues 维护着所有线程池的工作线程,工作窃取算法就是在这里进行的。

每一个 WorkQueue 对象中使用 pool 保留对 ForkJoinPool 的引用,用来获取其 WorkQueues 来窃取其他工作线程的任务来执行。

同时 WorkQueue 对象中的 owner 是 ForkJoinWorkerThread 工作线程,绑定 ForkJoinWorkerThread 和 WorkQueue 的一对一关系,每个工作线程会优先完成自己队列的任务,当自己队列中的任务为空时,才会通过工作窃取算法从其他任务队列中获取任务。

WorkQueue 中的 ForkJoinTask<?>[] array,是每一个具体的任务,插入 array 中的第一个任务是最大的任务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值