JUC入门(七)

14、ForkJoin

ForkJoin框架是Java中用于并行执行任务的框架,特别适合处理可以分解为多个子任务的复杂计算。它基于“分而治之”的思想,将一个大任务分解为多个小任务,这些小任务可以并行执行,最后将结果合并。

ForkJoin框架的核心组件

  1. ForkJoinPool:线程池,用于管理线程和任务的执行。

  2. RecursiveTask:有返回值的任务。

  3. RecursiveAction:无返回值的任务。

工作原理

  1. 任务分解:将大任务分解为多个小任务。

  2. 并行执行:小任务在ForkJoinPool中并行执行。

  3. 任务合并:将小任务的结果合并为最终结果。

  4. 工作窃取:线程池中的线程如果完成自己的任务,可以“窃取”其他线程的任务来执行,提高资源利用率。

代码示例:计算斐波那契数列

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;public class FibonacciExample {// 定义一个阈值,当任务大小小于这个值时,直接计算而不是进一步分解private static final int THRESHOLD = 10;public static void main(String[] args) {// 创建ForkJoinPoolForkJoinPool forkJoinPool = new ForkJoinPool();// 提交任务FibonacciTask task = new FibonacciTask(30);int result = forkJoinPool.invoke(task);// 输出结果System.out.println("Fibonacci(30) = " + result);}// 定义RecursiveTaskstatic class FibonacciTask extends RecursiveTask<Integer> {private final int n;public FibonacciTask(int n) {this.n = n;}@Overrideprotected Integer compute() {// 如果任务大小小于阈值,直接计算if (n <= THRESHOLD) {return computeFibonacci(n);} else {// 分解任务FibonacciTask leftTask = new FibonacciTask(n - 1);FibonacciTask rightTask = new FibonacciTask(n - 2);// 异步执行一个子任务leftTask.fork();// 执行另一个子任务int rightResult = rightTask.compute();// 等待第一个子任务完成并获取结果int leftResult = leftTask.join();// 合并结果return leftResult + rightResult;}}// 计算斐波那契数列的值private int computeFibonacci(int n) {if (n <= 1) {return n;}return computeFibonacci(n - 1) + computeFibonacci(n - 2);}}
}

代码解析

  1. ForkJoinPool

    • ForkJoinPoolForkJoin框架的核心,用于管理线程和任务的执行。在上面的代码中,我们创建了一个ForkJoinPool实例。

    • 使用invoke方法提交任务并获取结果。

  2. RecursiveTask

    • RecursiveTask是一个有返回值的任务类。在上面的代码中,我们定义了一个FibonacciTask类,继承自RecursiveTask<Integer>

    • compute方法中,我们实现了任务的分解和结果的合并。

  3. 任务分解

    • 如果任务大小小于阈值(THRESHOLD),直接计算结果。

    • 如果任务大小大于阈值,将任务分解为两个子任务:F(n - 1)F(n - 2)

    • 使用fork方法异步执行一个子任务,使用compute方法同步执行另一个子任务。

    • 使用join方法等待异步执行的子任务完成并获取结果。

  4. 结果合并

    • 将两个子任务的结果相加,得到最终结果。

下面详细阐述ForkJoin

. ForkJoinPool

ForkJoinPoolForkJoin框架的核心,用于管理线程和任务的执行。

构造方法
  • ForkJoinPool():创建一个默认的ForkJoinPool,其线程数量等于可用的处理器数量。

ForkJoinPool forkJoinPool = new ForkJoinPool();
  • ForkJoinPool(int parallelism):创建一个具有指定并行级别的ForkJoinPool
ForkJoinPool forkJoinPool = new ForkJoinPool(4); // 指定并行级别为4
常用方法
  • invoke(ForkJoinTask<?> task):执行给定的任务,等待其完成,并返回结果。
int result = forkJoinPool.invoke(new FibonacciTask(30));
  • execute(ForkJoinTask<?> task):异步执行给定的任务,不等待其完成。
forkJoinPool.execute(new FibonacciTask(30));
  • submit(ForkJoinTask<?> task):异步执行给定的任务,并返回一个ForkJoinTask对象,可以用来获取结果。
ForkJoinTask<Integer> task = forkJoinPool.submit(new FibonacciTask(30));
int result = task.get(); // 获取结果
  • shutdown():关闭线程池,不再接受新任务,但会等待已提交的任务完成。
forkJoinPool.shutdown();
  • shutdownNow():立即关闭线程池,尝试取消所有未完成的任务。
forkJoinPool.shutdownNow();

RecursiveTask

构造方法
  • RecursiveTask():无参构造方法,通常在子类中使用。
public class FibonacciTask extends RecursiveTask<Integer> {private final int n;public FibonacciTask(int n) {this.n = n;}
}
常用方法
  • compute():任务的主体,用于执行任务的逻辑。可以在这个方法中分解任务并调用forkjoin方法。
@Override
protected Integer compute() {if (n <= THRESHOLD) {return computeFibonacci(n);} else {FibonacciTask leftTask = new FibonacciTask(n - 1);FibonacciTask rightTask = new FibonacciTask(n - 2);leftTask.fork();int rightResult = rightTask.compute();int leftResult = leftTask.join();return leftResult + rightResult;}
}
  • fork():异步执行当前任务,返回一个ForkJoinTask对象。
leftTask.fork();
  • join():等待任务完成并获取结果。如果任务已经完成,直接返回结果。

RecursiveAction

RecursiveAction是一个无返回值的任务类,用于表示可以分解为多个子任务的任务。

构造方法
  • RecursiveAction():无参构造方法,通常在子类中使用。
public class SortTask extends RecursiveAction {private final int[] array;private final int start;private final int end;public SortTask(int[] array, int start, int end) {this.array = array;this.start = start;this.end = end;}
}
常用方法
  • compute():任务的主体,用于执行任务的逻辑。可以在这个方法中分解任务并调用forkjoin方法。
@Override
protected void compute() {if (end - start < THRESHOLD) {Arrays.sort(array, start, end);} else {int middle = (start + end) / 2;SortTask leftTask = new SortTask(array, start, middle);SortTask rightTask = new SortTask(array, middle, end);leftTask.fork();rightTask.compute();leftTask.join();}
}
  • fork():异步执行当前任务。
leftTask.fork();
  • join():等待任务完成。由于RecursiveAction没有返回值,join方法不返回任何结果。
leftTask.join();

总结

ForkJoin框架提供了多种方法来支持任务的分解、执行和结果合并。通过合理使用这些方法,可以高效地处理复杂的并行计算任务。以下是一些关键点:

  • ForkJoinPool:用于管理线程和任务的执行。

  • RecursiveTask:有返回值的任务类,适用于需要返回结果的任务。

  • RecursiveAction:无返回值的任务类,适用于不需要返回结果的任务。

  • compute():任务的主体,用于实现任务的逻辑。

  • fork():异步执行任务。

  • join():等待任务完成并获取结果(对于RecursiveTask)或等待任务完成(对于RecursiveAction)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第 7 章:综合回顾与性能优化

本章目标: 系统化地回顾各类外设接口选型原则 深入探讨多接口并存时的资源冲突与管理策略 掌握软硬件协同的性能分析方法,快速定位并消除瓶颈 总结一整套从架构设计到现场调试的最佳实践与防坑指南 7.1 综合选型决策矩阵(深度分析) 除了前文的基础矩阵,这里引入两个更细化…

交换机的连接方式堆叠和级联

以下是交换机的堆叠和级联各自的优缺点总结&#xff0c;帮助快速对比选择&#xff1a; ​一、堆叠&#xff08;Stacking&#xff09;​ ​优点 ​高性能 堆叠链路带宽高&#xff08;如10G/40G/100G&#xff09;&#xff0c;成员间数据通过背板直连&#xff0c;无带宽瓶颈。支…

C++高效求解非线性方程组的实践指南

非线性方程组的求解是科学与工程计算中的核心问题之一&#xff0c;涉及物理建模、机器学习、金融分析等多个领域。C因其高性能和底层控制能力成为此类问题的首选语言&#xff0c;但如何高效实现求解仍存在诸多挑战。本文从算法选择、工具应用、稳定性优化及性能提升四个维度&am…

2025年- H42-Lc150 --146. LRU缓存(哈希表,双链表)需二刷--Java版

1.题目描述 2.思路 LRU(最近最少使用&#xff09;&#xff1a;如果缓存的容量为2&#xff0c;刚开始的两个元素都入栈。之后该2元素中有其中一个元素&#xff08;重点元素&#xff09;被访问。把最近访问过的重点元素保留&#xff0c;另一个边缘元素就得离开缓存了。 下面是l…

5G 网络中 DNN 的深度解析:从基础概念到核心应用

摘要 本文深度剖析 5G 网络中 DNN(数据网络名称)的核心作用与运行机制,从基础概念入手,详细阐述 DNN 在会话管理、用户面资源分配、切片选择等方面的关键功能。通过实际应用场景分析与技术实现细节探讨,揭示 DNN 如何助力 5G 网络满足多样化业务需求,为 5G 网络部署、优…

MLpack 开源库介绍与使用指南

MLpack 开源库介绍与使用指南 1. MLpack 简介 MLpack 是一个快速、灵活的 C 机器学习库&#xff0c;专注于可扩展性、速度和易用性。它提供了大量经典的机器学习算法实现&#xff0c;包括&#xff1a; 监督学习&#xff08;分类、回归&#xff09;无监督学习&#xff08;聚类…

Python版scorecardpy库woebin函数使用

scorecardpy 是一款专门用于评分卡模型开发的 Python 库&#xff0c;由谢士晨博士开发&#xff0c;该软件包是R软件包评分卡的Python版本。量级较轻&#xff0c;依赖更少&#xff0c;旨在简化传统信用风险计分卡模型的开发过程&#xff0c;使这些模型的构建更加高效且易于操作。…

英语写作中“假设”suppose, assume, presume 的用法

一、suppose 是给出推理的前提&#xff0c;与事实无关&#xff0c;例如&#xff1a; Suppose x >0. Then the square root of x is a real number. &#xff08;假设x大于0&#xff0c;则x的平方根是实数。&#xff09; Suppose Jack and Alice share a private channel. …

CAD标注样式如何设置?详细教程来了

CAD中有很多的标注&#xff0c;比如线性标注&#xff0c;对齐标注&#xff0c;坐标标注&#xff0c;面积标注&#xff0c;直径标注&#xff0c;弧长标注等等&#xff0c;标注的种类多&#xff0c;标注的样式也多&#xff0c;今天来给大家介绍一下浩辰CAD看图王中如何设置不同的…

vscode include总是报错

VSCode 的 C/C 扩展可以通过配置 c_cpp_properties.json 来使用 compile_commands.json 文件中的编译信息&#xff0c;包括 include path、编译选项等。这样可以确保 VSCode 的 IntelliSense 与实际编译环境保持一致。 方法一&#xff1a;直接指定 compile_commands.json 路径…

自动化立体仓库WCS与PLC通讯设计规范

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。欢迎大家使用我们的仓储物流技术AI智能体。 新书《智能物流系统构成与技术实践》 新书《智能仓储项目出海-英语手册&#xff0c;必备&#xff01;》 完整版文件和更多学习资料&#xf…

【window QT开发】简易的对称密钥加解密工具(包含图形应用工具和命令行工具)

前言 项目开发时&#xff0c;配置文件中某些信息不适合直接明文显示&#xff0c;本文提供基于对称密钥的AES-256算法的加解密工具&#xff0c;可集成到项目中。 AES讲解 以下是我分享的一个在国产信创系统(Linux)下使用openssl实现AES加解密的博文 对称加密--AES加解密 本文…

「极简」扣子(coze)教程 | 小程序UI设计进阶(二)!让系统动起来,“禁用”,“加载”状态设置

大家好&#xff0c;上一期大师兄通过一个例子来介绍一下扣子界面中“可见性”的应用。今天大师兄想再进一步介绍控件中的其他一些重要的属性。 扣子&#xff08;coze&#xff09;编程 「极简」扣子(coze)教程 | 小程序UI设计进阶&#xff01;控件可见性设置 「极简」扣子(coze…

前端三件套之html详解

目录 一 认识 二 标签的分类 三 标签 body标签 标题标签 段落标签 换行标签 水平分割线 文本格式化标签 图片标签 音频标签 链接标签 列表标签 表格标签 表单标签 input标签 下拉菜单标签 textarea文本域标签 label标签 语义化标签 button标签 字符实体 …

Google Play 账号创建及材料准备

1&#xff1a;注册一个关联Google Play账号的Google账号&#xff0c;关联邮箱进行自动转发 2&#xff1a;准备一张Visa、Master、JCB、运通卡或Discover等美国信用卡或全球付虚拟信用卡&#xff0c;用来支付25美金的GP账号注册费 3&#xff1a;为避免出现关联原因被封&#x…

Pycharm和Flask的学习心得(4和5)

一&#xff1a;认识路由&#xff1a; &#xff08;1&#xff09;&#xff1a;接受请求的类型&#xff1a; app.route(hello ,methods [GET ,POST]) 请求类型主要有两种(常用)&#xff1a;GET 和 POST ; GET: 直接输入的网址&#xff08;url访问的就是GET请求&#xff09; …

DeepSeek 赋能智能电网:从技术革新到全场景应用实践

目录 一、智能电网的发展现状与挑战二、DeepSeek 技术解析2.1 DeepSeek 技术原理2.2 DeepSeek 技术优势 三、DeepSeek 在智能电网中的具体应用3.1 设备管理智能化3.2 电网运行优化3.3 客户服务提升3.4 规划建设智能化3.5 经营管理高效化3.6 办公辅助便捷化 四、DeepSeek 在智能…

MFC 编程中 OnInitDialog 函数

核心作用 对话框初始化入口 &#xff1a;创建完成后第一个执行的函数。是对话框的起点。控件操作安全期 &#xff1a;此时所有控件已创建完成。可以安全地进行控件的初始化、属性设置等操作。界面布局最佳时机 &#xff1a;窗口显示前完成初始化设置。可以进行布局调整、数据初…

前端地图数据格式标准及应用

前端地图数据格式标准及应用 坐标系EPSGgeojson标准格式基于OGC标准的地图服务shapefile文件3D模型数据常见地图框架 坐标系EPSG EPSG&#xff08;European Petroleum Survey Group&#xff09;是一个国际组织&#xff0c;负责维护和管理地理坐标系统和投影系统的标准化编码 E…

Python爬虫(35)Python爬虫高阶:基于Docker集群的动态页面自动化采集系统实战

目录 一、技术演进与行业痛点二、核心技术栈深度解析2.1 动态渲染三件套2.2 Docker集群架构设计2.3 自动化调度系统 三、进阶实战案例3.1 电商价格监控系统1. 技术指标对比2. 实现细节 3.2 新闻聚合平台1. WebSocket监控2. 字体反爬破解 四、性能优化与运维方案4.1 资源消耗对比…