JUC高并发编程11:Fork/Join分支合并框架

1 Fork/Join 框架简介

Fork/Join 框架是 Java 7 引入的一种并行编程框架,用于将一个大任务拆分成多个小任务进行并行处理,最后将子任务的结果合并成最终的计算结果。Fork/Join 框架的核心思想是将任务递归地分解为更小的子任务,直到子任务足够简单,可以直接执行。然后,框架会将这些子任务的结果合并,最终得到整个任务的结果。

1.1 Fork/Join 框架的主要组件

  1. ForkJoinPool:一个特殊的线程池,用于执行 Fork/Join 任务。
  2. ForkJoinTask:表示一个可以被 Fork/Join 框架执行的任务。通常使用其子类 RecursiveTask(有返回值)或 RecursiveAction(无返回值)。
  3. RecursiveTask:表示一个有返回值的任务,通常用于需要返回结果的任务。
  4. RecursiveAction:表示一个无返回值的任务,通常用于不需要返回结果的任务。

1.2 Fork/Join 框架的工作原理

  1. Fork:将一个复杂的任务分解为多个子任务,直到子任务足够简单,可以直接执行。
  2. Join:将子任务的结果合并,最终得到整个任务的结果。

1.3 Fork/Join 框架的优点

  • 并行处理:能够充分利用多核处理器的优势,提高任务的执行效率。
  • 任务分解:能够将复杂的任务分解为多个简单的子任务,简化任务的处理逻辑。
  • 结果合并:能够自动将子任务的结果合并,得到最终的结果。

2 Fork/Join 框架的实现原理

2.1 ForkJoinPool 的组成

ForkJoinPool 由两个主要部分组成:

  1. ForkJoinTask 数组:负责存放以及将任务提交给 ForkJoinPool。
  2. ForkJoinWorkerThread 数组:负责执行这些任务。

2.2 Fork 方法

当我们调用 ForkJoinTask 的 fork 方法时,程序会把任务放在 ForkJoinWorkerThread 的 workQueue 中,异步地执行这个任务,然后立即返回结果。

public final ForkJoinTask<V> fork() {Thread t;if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)((ForkJoinWorkerThread)t).workQueue.push(this);elseForkJoinPool.common.externalPush(this);return this;
}

pushTask 方法把当前任务存放在 ForkJoinTask 数组队列里,然后再调用 ForkJoinPool 的 signalWork() 方法唤醒或创建一个工作线程来执行任务。

final void push(ForkJoinTask<?> task) {ForkJoinTask<?>[] a; ForkJoinPool p;int b = base, s = top, n;if ((a = array) != null) { // ignore if queue removedint m = a.length - 1; // fenced write for task visibilityU.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);U.putOrderedInt(this, QTOP, s + 1);if ((n = s - b) <= 1) {if ((p = pool) != null)p.signalWork(p.workQueues, this);//执行}else if (n >= m)growArray();}
}

2.3 Join 方法

Join 方法的主要作用是阻塞当前线程并等待获取结果。ForkJoinTask 的 join 方法的实现如下:

public final V join() {int s;if ((s = doJoin() & DONE_MASK) != NORMAL)reportException(s);return getRawResult();
}

它首先调用 doJoin 方法,通过 doJoin() 方法得到当前任务的状态来判断返回什么结果。任务状态有 4 种:已完成(NORMAL)、被取消(CANCELLED)、信号(SIGNAL)和出现异常(EXCEPTIONAL)。

  • 如果任务状态是已完成,则直接返回任务结果。
  • 如果任务状态是被取消,则直接抛出 CancellationException。
  • 如果任务状态是抛出异常,则直接抛出对应的异常。

doJoin 方法的实现如下:

private int doJoin() {int s; Thread t; ForkJoinWorkerThread wt; ForkJoinPool.WorkQueue w;return (s = status) < 0 ? s :((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?(w = (wt = (ForkJoinWorkerThread)t).workQueue).tryUnpush(this) && (s = doExec()) < 0 ? s :wt.pool.awaitJoin(w, this, 0L) :externalAwaitDone();
}

doExec 方法的实现如下:

final int doExec() {int s; boolean completed;if ((s = status) >= 0) {try {completed = exec();} catch (Throwable rex) {return setExceptionalCompletion(rex);}if (completed)s = setCompletion(NORMAL);}return s;
}

doJoin() 方法流程如下:

  1. 首先通过查看任务的状态,看任务是否已经执行完成,如果执行完成,则直接返回任务状态。
  2. 如果没有执行完,则从任务数组里取出任务并执行。
  3. 如果任务顺利执行完成,则设置任务状态为 NORMAL,如果出现异常,则记录异常,并将任务状态设置为 EXCEPTIONAL。

2.4 Fork/Join 框架的异常处理

ForkJoinTask 在执行的时候可能会抛出异常,但是我们没办法在主线程里直接捕获异常。ForkJoinTask 提供了 isCompletedAbnormally() 方法来检查任务是否已经抛出异常或已经被取消了,并且可以通过 getException 方法获取异常。

public final Throwable getException() {int s = status & DONE_MASK;return ((s >= NORMAL) ? null :(s == CANCELLED) ? new CancellationException() :getThrowableException());
}

getException 方法返回 Throwable 对象,如果任务被取消了则返回 CancellationException,如果任务没有完成或者没有抛出异常则返回 null。

2.5 小结

Fork/Join 框架通过将大任务分解为多个小任务,并行处理这些小任务,最后将结果合并,能够有效地提高任务的执行效率。适用于需要并行处理的任务,如数组计算、树遍历等。通过合理设置任务分解的阈值,可以平衡任务的分解和合并的开销,达到最佳的性能。

3 案例实现

场景:生成一个计算任务,计算1+2+3+4+…+100,要求相加两个数,差值不超过10,如果超过10,继续拆分

class MyTask extends RecursiveTask<Integer>{// 拆分差值不能超过10,计算10以内的运算private static  final Integer VALUE = 10;private int begin;  // 拆分开始值private int end;    // 拆分结束值private int result; // 返回结果// 创建有参构造public MyTask(int begin,int end){this.begin = begin;this.end = end;}// 拆分和合并过程@Overrideprotected Integer compute() {// 判断相加两个数值是否大于10if(end - begin <= VALUE){// 相加操作for (int i = begin; i <= end; i++) {result = result + i;}} else {// 进一步拆分// 获取中间值int middle = (begin + end)/2;// 拆分左边MyTask myTask01 = new MyTask(begin, middle);// 拆分右边MyTask myTask02 = new MyTask(middle + 1, end);// 调用方法拆分myTask01.fork();myTask02.fork();// 合并结果result = myTask01.join() + myTask02.join();}return result;}
}
public class ForkJoinDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建MyTask对象MyTask myTask = new MyTask(0, 100);// 创建分支合并池对象ForkJoinPool forkJoinPool = new ForkJoinPool();ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);// 获取最终合并之后的结果Integer result = forkJoinTask.get();System.out.println(result);// 关闭池对象forkJoinPool.shutdown();}
}

4 思维导图

在这里插入图片描述

5 参考链接

【【尚硅谷】大厂必备技术之JUC并发编程】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1560753.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Zilliz获Forrester报告全球第一;OB支持向量能力;Azure发布DiskANN;阿里云PG发布内置分析引擎

重要更新 1. Azure发布PostgreSQL向量索引扩展DiskANN&#xff0c;声称在构建HNSW/IVFFlat索引上&#xff0c;速度、精准度都超越pg_vector&#xff0c;并解决了pg_vector长期存在的偶发性返回错误结果的问题( [1] )。 2. 阿里云RDS PostgreSQL 发布AP加速引擎&#xff08;rds…

Rust编程的函数

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 7.1 函 数 定 义 在Rust中&#xff0c;函数使用fn关键字定义&#xff0c;后跟函数…

干货资料速来领取!!

关于【中国ICD行业 PLM市场研究报告】: 作为电子产业的工业粮食,ICD(集成电路设计)是一个高度专业化的领域,当前已广泛应用于计算机、通信、消费电子、汽车、医疗设备等多个行业。 近年来,国家发布多项积极政策,助推行业快速发展来提升自主可控技术及国际市场竞争力,…

数字创意的孵化器:西安园区打造创意产业生态圈

在数字创意蓬勃发展的时代浪潮中&#xff0c;西安犹如一颗闪耀的新星&#xff0c;凭借着独特的园区建设&#xff0c;为数字创意产业注入无限活力。其中&#xff0c;西安数字创意孵化园区正发挥着不可替代的重要作用&#xff0c;尤其是西安国际数字影像产业园&#xff0c;更是成…

卡门涡街,大自然的诗意律动

1959年8月14日&#xff0c;人类拍摄了地球的首张卫星图像。半个多世纪后&#xff0c;地球已经被上万颗卫星环绕&#xff0c;传回的自拍也越来越清晰。2009年&#xff0c;美国宇航局对过去50年的地球卫星图进行评选&#xff0c;排第一名的是这一张&#xff0c;太平洋上的风流过阿…

面试还搞不懂redis,快看看这40道面试题

Redis 面试题 1、什么是 Redis?. 2、Redis 的数据类型&#xff1f; 3、使用 Redis 有哪些好处&#xff1f; 4、Redis 相比 Memcached 有哪些优势&#xff1f; 5、Memcache 与 Redis 的区别都有哪些&#xff1f; 6、Redis 是单进程单线程的&#xff1f; 7、一个字符串类…

食品研发PLM系统是什么?三品PLM食品行业解决方案详情介绍

在快速变化的食品行业中&#xff0c;企业面临着诸多挑战&#xff0c;特别是在产品研发管理方面。随着消费者对食品品质、健康、创新等方面需求的不断提升&#xff0c;食品企业必须在产品研发上不断创新&#xff0c;以满足市场需求。然而&#xff0c;这一过程中&#xff0c;食品…

数据分布过于集中 怎么办,python 人工智能 ,数据分析,机器学习pytorch tensorflow ,

数据分布过于集中&#xff0c;意味着数据的大部分值都聚集在某个特定区间内&#xff0c;这可能会导致统计分析的结果不够稳健&#xff0c;或者模型训练时出现过拟合等问题。针对这种情况&#xff0c;可以考虑以下几种方法来处理&#xff1a; 变换成 1. **数据转换**&#xff1…

服装生产管理的现代化:SpringBoot框架

2 关键技术简介 2.1 JAVA技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0…

ssm某物流企业管理信息系统-计算机毕业设计源码82788

目录 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1系统开发流程 2.2.2 用户登录流程 2.2.3 系统操作流程 2.2.4 添加信息流程 2.2.5 修改信息流程 2.2.6 删除信息流程 2.3 系统功能分析 …

Windows下MYSQL8.0如何恢复root权限

误操作把root权限清掉导致数据库无法登录&#xff08;确实很难受&#xff09;&#xff0c;在网上找了很多方法&#xff0c;发现没有很行之有效的方法&#xff0c;在多方尝试终于找到了适合敏感宝宝体质的方法。 C:\Users\Administrator>mysql -u root -P3307 ERROR 1045 (2…

《征服数据结构》并查集(DSU)

摘要&#xff1a; 1&#xff0c;并查集的介绍 2&#xff0c;并查集的查找 3&#xff0c;并查集的合并 1&#xff0c;并查集的介绍 并查集(Disjoint-set data structure&#xff0c;不交集数据结构)是用于处理一些不交集的合并以及查询问题&#xff0c;它是非常重要的一种数据结…

【开源】RISC-V 修改neofetch中的Host描述

neofetch 介绍 neofetch 是一款用于在终端中显示系统信息的工具&#xff0c;其主要特点是以美观的方式展示宿主机的基本信息。它通常用于展示系统的分发版本、内核版本、硬件信息、桌面环境&#xff0c;以及一些个性化的设置&#xff0c;配合 ASCII 艺术风格的 logo&#xff0…

【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第三十章 文件IO和标准IO

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

【杭州马拉松:挑战自我,突破极限的征程】

2024年11月3日&#xff0c;杭州马拉松如约而至。这场挑战自我&#xff0c;突破极限的征程&#xff0c;将在杭州这座美丽的城市揭开序幕。对于广大跑步爱好者来说&#xff0c;如何选择合适的装备参加马拉松&#xff0c;成为了备战的重中之重。 在这里&#xff0c;我要向大家推荐…

2024咸宁中、初级职称申报时间是什么时候?

根据省职改办《关于做好2023年度全省职称评审工作的通知》&#xff08;鄂职改办〔2024〕16号&#xff09;、市职改办《关于做好2024年度咸宁市专业技术职务任职资格评审工作有关事项的通知》&#xff08;咸职改办〔2024〕11号&#xff09;等文件精神&#xff0c;现就开展2024年…

Anaconda简介windows安装

Anaconda Anaconda简介1.下载anaconda2.安装anaconda3.验证是否安装成功4.运行Anaconda简介 Anaconda是一个Python发行版本,其包含了conda、Python等180多个科学包及其依赖项,它是科学计算领域非常流行的Python包以及集成环境管理的应用。它的优势主要表现在以下几个方面: …

SSM志愿服务管理系统-计算机毕业设计源码64777

目 录 摘要 1 绪论 1.1 研究背景 1.2研究意义 1.3论文结构与章节安排 2 志愿服务管理系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用…

Python酷库之旅-第三方库Pandas(142)

目录 一、用法精讲 641、pandas.Timestamp.hour属性 641-1、语法 641-2、参数 641-3、功能 641-4、返回值 641-5、说明 641-6、用法 641-6-1、数据准备 641-6-2、代码示例 641-6-3、结果输出 642、pandas.Timestamp.is_leap_year属性 642-1、语法 642-2、参数 6…

论文写作常用的七类辅助工具

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 论文写作过程中&#xff0c;以下七类常用的辅助工具&#xff0c;可以帮助提升效率、确保内容准确性、提高整体写作质量。 1. 文献管理工具 EndNote&#xff1a;用于管理参考文献&#…