JAVA 多线程之ForkJoin

news/2024/11/9 3:47:52/
Fork/Join 框架是jdk7提供的一个用于并行执行任务的框架,是一个把大任务分成若干小任务,最终汇总每个小任务结果,最终得到大任务计算结果的框架。Fork:就是把一个大任务切分成若干小任务,并行执行;Join:就是合并这些小任务的执行结果,最终得到大任务的结果。Fork/Join 根据工作窃取算法进行设计工作窃取算法
(work-stealing),是指某个线程从其他队列里窃取任务来执行。为什么需要工作窃取算法假如有些线程一起工作,可能有些线程的工作早早结束,结束的线程与其等着,不如去帮其他线程干活,于是就去其他线程的队列里,窃取一个任务来执行。而在这时,他们会访问同一队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列维护;被窃取任务的线程永远从双端队列头部拿取任务执行;窃取任务线程永远从双端队列尾部拿取任务执行;Fork/Join 框架设计:Fork:分割任务。首先,我们需要一个fork类,来把大任务拆分成子任务,有可能子任务还很大,需要不停的分割,直到分割出子任务足够小。抽象类ForkJoinTask提供了两个子抽象类RecursiveAction:没有返回结果的任务RecursiveTask:有返回结果的任务Join:执行任务并合并结果。分割的子任务分别放在双端队列里,然后几个启动线程分别从双端队列里获取线程并执行。子任务执行完的结果同一放到一个队列里,启动一个线程从队列里拿数据然后合并这些数据ForkJoinPool :ForkJoinTask需要通过ForkJoinPool来执行使用场景:可以采用分而治之的算法场景计算密集型的任务示例:
计算 1+2+3+……+100,如果加数之间差值大于等于10,则拆分为子任务。
java">package org.test.mem.thread.pool.forkjoin;import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;/*** Fork/Join 框架是jdk7提供的一个用于并行执行任务的框架,是一个把大任务分成若干小任务,最终汇总每个小任务结果,最终得到大任务计算结果的框架。* <p>* Fork:就是把一个大任务切分成若干小任务,并行执行;* Join:就是合并这些小任务的执行结果,最终得到大任务的结果。* <p>* Fork/Join 根据工作窃取算法进行设计* <p>* 工作窃取算法:(work-stealing),是指某个线程从其他队列里窃取任务来执行。** 为什么需要工作窃取算法?* 假如有些线程一起工作,可能有些线程的工作早早结束,结束的线程与其等着,不如去帮其他线程干活,于是就去其他线程的队列里,窃取一个任务来执行。* 而在这时,他们会访问同一队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列维护;* 被窃取任务的线程永远从双端队列头部拿取任务执行;* 窃取任务线程永远从双端队列尾部拿取任务执行;** Fork/Join 框架设计:* Fork:分割任务。首先,我们需要一个fork类,来把大任务拆分成子任务,有可能子任务还很大,需要不停的分割,直到分割出子任务足够小。*   抽象类ForkJoinTask提供了两个子抽象类*      RecursiveAction:没有返回结果的任务*      RecursiveTask:有返回结果的任务** Join:执行任务并合并结果。分割的子任务分别放在双端队列里,然后几个启动线程分别从双端队列里获取线程并执行。子任务执行完的结果同一放到一个队列里,启动一个线程从队列里拿数据* 然后合并这些数据**  ForkJoinPool :ForkJoinTask需要通过ForkJoinPool来执行*** 使用场景:* 可以采用分而治之的算法场景* 计算密集型的任务** 实例:* 计算 1+2+3+……+100,如果加数之间差值大于等于10,则拆分为子任务。** */
public class ForkJoinTest extends RecursiveTask<Integer> {private static final int THRESHOLD = 10;private int start;private int end;public ForkJoinTest(int start, int end) {this.start = start;this.end = end;}public static void main(String[] args) {ForkJoinPool forkJoinPool = new ForkJoinPool();//计算任务ForkJoinTest task = new ForkJoinTest(1, 100);//异步执行任务ForkJoinTask<Integer> result = forkJoinPool.submit(task);try {System.out.println(result.get());} catch (InterruptedException e) {throw new RuntimeException(e);} catch (ExecutionException e) {throw new RuntimeException(e);}}@Overrideprotected Integer compute() {int sum = 0;if (end - start < THRESHOLD) {for (int i = start; i <= end; i++) {sum += i;
//                System.out.println(Thread.currentThread().getName() + ":" + i + " sum:" + sum);}System.out.println(Thread.currentThread().getName() +" sum:" +sum +" start:"+start+" end:"+end);return sum;}else{int middle = (end + start) / 2;ForkJoinTest leftForkJoin = new ForkJoinTest(start, middle);ForkJoinTest rightForkJoin = new ForkJoinTest(middle + 1, end);leftForkJoin.fork();rightForkJoin.fork();int leftResult = leftForkJoin.join();int rightResult = rightForkJoin.join();sum = leftResult + rightResult;return sum;}}
}


http://www.ppmy.cn/news/1545517.html

相关文章

AI预测体彩排3采取888=3策略+和值012路+胆码+通杀1码测试11月8日升级新模型预测第128弹

经过100多期的测试&#xff0c;当然有很多彩友也一直在观察我每天发的预测结果&#xff0c;得到了一个非常有价值的信息&#xff0c;那就是9码定位的命中率非常高&#xff0c;已到达90%的命中率&#xff0c;这给喜欢打私菜的朋友提供了极高价值的预测结果~当然了&#xff0c;大…

蓝桥杯 Python组-神奇闹钟(datetime库)

神奇闹钟 传送门&#xff1a; 0神奇闹钟 - 蓝桥云课​​​​​​ 问题描述 小蓝发现了一个神奇的闹钟&#xff0c;从纪元时间&#xff08;1970 年 11 日 00&#xff1a;00&#xff1a;00&#xff09;开始&#xff0c;每经过 x 分钟&#xff0c;这个闹钟便会触发一次闹铃 (…

【Git】Git 版本控制与协作开发指南

目录 引言1. 从远程仓库拉取代码1.1 克隆仓库1.2 克隆特定分支1.3 使用 SSH 克隆 2. 在本地修改代码2.1 进入仓库目录 2.2 查看本地分支2.2 创建新的本地分支2.4 编辑代码 3. 提交修改到云端仓库3.1 检查状态3.2 添加更改3.3 提交更改3.4 推送更改到远程仓库3.5 拉取代码并提交…

记录一次node节点异常的排查

场景&#xff1a;运维同事反馈&#xff0c;在部署服务的时候&#xff0c;云上的k8s的node节点突然异常了&#xff0c;而且是3个节点同时异常了。当时开发人员正在部署服务&#xff0c;并没有做其他的操作。而且之前3个node节点也没有异常现象&#xff0c;查看运维管理的事件中心…

高级 <HarmonyOS主题课>让您的应用拥有领先的位置服务能力的课后习题

天之道&#xff0c;其犹张弓与&#xff1f; 高者抑下&#xff0c;下者举之&#xff0c;有余者损之&#xff0c;不足者补之。 天之道&#xff0c;损有余而补不足。 人之道&#xff0c;则不然&#xff0c;损不足以奉有余。 孰能有余以奉天下&#xff0c;唯有道者。 是以圣人为而不…

用示例来看C2Rust工具的使用和功能介绍

C2Rust可以将C语言的源代码转换成Rust语言的源代码。下面是一个简单的C语言代码示例,以及使用c2Rust工具将其转换为Rust安全代码的过程。 C语言源代码示例 // example.c #include <stdio.h>int add(int a, int b)

在 Vue 中实现与优化轮询技术

轮询&#xff08;Polling&#xff09;是一种计算机程序反复检查某个条件或状态的技术&#xff0c;通常用于在一定的时间间隔内不断请求信息或更新数据状态。轮询被广泛应用于前端开发&#xff08;例如实现页面实时更新&#xff09;、后端服务监控、网络设备状态检查等场景。 1…

NetCore使用Aop和内存缓存对接口、方法进行数据缓存

通过Aop内存缓存对接口、方法进行缓存 源码地址https://gitee.com/wangbenchi66/nuget 1. nuget包引入 必须引入包 至少在2024.11.7以上 <PackageReference Include"WBC66.Cache.Core" Version"2024.11.7" />必须开启内存缓存 否则后续步骤无法正…