【JUC】十、ForkJoin

文章目录

  • 1、分支合并框架
  • 2、案例
  • 3、ForkJoinTask
  • 4、工作窃取算法
  • 5、ForkJoinPool

一个个任务执行在一个个线程上,倘若某一个任务耗时很久,期间其他线程都无事可做,显然没有利用好多核CPU这一计算机资源,因此,出现了"分而治之"的解决方案。

在这里插入图片描述

1、分支合并框架

Fork/Join即分支合并,用处是把一个大任务拆分成多个子任务来并行处理,最后再合并子任务的结果。(since Java1.7)

  • Fork:把一个复杂的任务进行拆分,大事化小
  • Join:把拆分的子任务的结果做合并

示意图:

在这里插入图片描述

举个实际例子:
在这里插入图片描述

2、案例

以下采用分支合并框架来实现1+2+…+100

在这里插入图片描述

通过继承RecursiveTask类自定义任务,泛型为result的类型:

//自定义任务类继承RecursiveTask
class MyTask extends RecursiveTask<Integer> {//拆分差值不超过10,来计算10以内的运算private static final int 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 task01 = new MyTask(begin, middle);//右边MyTask task02 = new MyTask(middle + 1, end);//调用方法拆分task01.fork();task02.fork();//合并结果result = task01.join() + task02.join();}return result;}
}

以上自定义Task中体现的思路就是:问题足够小的时候,直接处理,否则就继续拆分。创建forkjoinpool对象,提交任务,获取执行结果:

public class ForkJoinDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {//创建拆分任务对象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();}}

结果:

5050

3、ForkJoinTask

在这里插入图片描述
ForkJoinTask有两个子类:Recursive即递归的意思

  • RecursiveTask:有返回值的任务
  • RecursiveAction:没有返回值的任务

ForkJoinTask还实现了Future接口,即说明是一个可以异步获取结果的任务。常用方法有:

  • fork:分割子任务,判断当前线程是否可以转型为ForkJoinWorkerThread类型,即是不是通过ForkJoinPool线程池执行的ForkJoinTask,是就push到队列里

在这里插入图片描述

  • 合并子任务结果:join
//调用方法拆分
task01.fork();
task02.fork();
//合并结果
result = task01.join() + task02.join();
  • 获取任务执行结果:get,即等待任务执行完成并返回任务计算结果

【方法源码详解参考这篇】

4、工作窃取算法

先看类ForkJoinWorkerThread类,它是执行前面ForkJoinTask的线程。ForkJoin框架使用的线程维护了一个双端队列,并通过工作窃取算法(work-stealing)来提高任务执行的效率。

在这里插入图片描述

工作窃取算法,在ForkJoin框架中就是一个线程的任务队列里的活儿都干完了,就去其他线程维护的任务队列的尾部窃取一个任务来执行。用张网图示意:

在这里插入图片描述

因此:

  • 对于线程自身维护的任务队列,线程自身执行任务的顺序是后进先出
  • 对于窃取其他线程队列的线程,则是先进先出(从队尾窃取并执行)

如图,对于线程1,任务的出入队都在队首,而负责窃取任务的线程2,其从队尾取任务,也就是说,只有线程1的任务队列只剩最后一个任务的时候,才会抢夺一次锁。如此,就大大提高了并发任务的执行效率。

5、ForkJoinPool

FoolJoinPool是运行ForkJoinTask的线程池,同ThreadPoolExecutor一样,也实现了Executor和ExecutorService接口

在这里插入图片描述

任务提交到ForkJoinPool后,池里维护的线程来执行任务

ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);

其构造方法有四个参数:

public ForkJoinPool(int parallelism,ForkJoinWorkerThreadFactory factory,UncaughtExceptionHandler handler,boolean asyncMode){
//.....

分别是:

  • parallelism:期望并发数,默认会使用Runtime.getRuntime().availableProcessors()的值,即当前计算机可用的CPU数量
  • factory:创建ForkJoin工作线程的工厂,默认为defaultForkJoinWorkerThreadFactory
  • handler:执行任务时遇到不可恢复的错误时的处理程序,默认为null
  • asyncMode:工作线程获取任务使用FIFO(先进先出)模式还是LIFO模式,默认为LIFO(后进先出)

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

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

相关文章

13 redis中的复制的拓扑结构

1、一主一从 为了性能考虑&#xff0c;主节点可以不开启AOF&#xff0c;但是要避免重启。 2、一主多从 适用于读操作的场景。由于从节点多&#xff0c;所以主的复制压力大 3、树状主从 数据先同步到redisB,redisC从节点C,E来看&#xff0c;redisB相当于主机了&#xff0c;可以…

【JavaEE】Servlet实战案例:表白墙网页实现

一、功能展示 输入信息&#xff1a; 点击提交&#xff1a; 二、设计要点 2.1 明确前后端交互接口 &#x1f693;接口一&#xff1a;当用户打开页面的时候需要从服务器加载已经提交过的表白数据 &#x1f693;接口二&#xff1a;当用户新增一个表白的时候&#xff0c;…

玩转系统|长亭雷池WAF详细使用教程——深入了解

目录 配置防护站点 界面操作​ 如何配置域名、端口、上游服务器​ 工作原理​ 在单独设备上部署雷池&#xff08;推荐&#xff09;​ 直接在网站服务器上部署雷池​ 和其他反代设备一起部署的情况​ 配置后网站无法访问&#xff0c;如何排查​ 测试防护效果 确认网站…

ETL-使用kettle批量复制sqlserver数据到mysql数据库

文章标题 1、安装sqlserver数据库2、下载kettle3、业务分析4、详细流程&#xff08;1&#xff09;转换1&#xff1a;获取sqlserver所有表格名字&#xff0c;将记录复制到结果&#xff08;2&#xff09;转换2&#xff1a;从结果设置变量&#xff08;3&#xff09;转换3&#xff…

【广州华锐互动】VR溺水预防教育:在虚拟世界中学会自救!

在现代社会中&#xff0c;水上安全和救援行动的重要性不言而喻。尤其在自然灾害、游泳事故或航海事故中&#xff0c;有效的救援行动可以挽救许多生命。然而&#xff0c;传统的救援训练往往存在成本高、风险大、效率低等问题。在这样的背景下&#xff0c;虚拟现实&#xff08;VR…

Oracle实时同步技术

Oracle数据库的价值 Oracle数据库是一种高度可靠、安全和强大的关系型数据库管理系统&#xff0c;它具有以下几个方面的价值&#xff1a; 可靠性和稳定性&#xff1a;Oracle数据库以其高度可靠性、稳定性和数据完整性而闻名于世。 安全性&#xff1a;Oracle数据库提供了一系列…

【linux】安装telnet

Telnet Telnet协议是TCP/IP协议族中的一员&#xff0c;是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序&#xff0c;用它连接到服务器。终端使用者可以在telnet程序中输入命令&#xf…

子虔科技亮相2023工业软件生态大会 以先进理念赋能工业软件发展

作为云化工业软件领先企业&#xff0c;子虔科技携多项全新云原生产品亮相2023工业软件生态大会。 本届大会以“共建新一代工业软件体系&#xff0c;引领制造业高质量发展”为主题&#xff0c;集结行业领先企业、行业专家探究工业软件在核心技术、产业链创新和生态建设等方面创…

XmlElement注解在Java的数组属性上,以产生多个相同的XML元素

例如&#xff0c;下面这段XML数据&#xff0c;有多个data元素&#xff0c;并且它们级别相同: <?xml version"1.0" encoding"UTF-8"?><request><reqtype>05</reqtype><secret>test</secret><body><userid&…

将Excel中的数据导入shell脚本,并调用expect脚本

主脚本test.sh #!/bin/bash # 设置超时时间 set timeout 240 # 将 Excel 文件转换为 CSV 格式 # test.xlsx > temp.csv # 初始化一个二维数组 declare -A data # 逐行读取 CSV 文件&#xff0c;并将每个单元格的数据存储在二维数组中 row1 while IFS, read -r col1 col2 co…

综述---知识蒸馏

3.1 图神经网络的发展与轻量级框架下的知识蒸馏 图数据无处不在&#xff0c;图神经网络的研究也蓬勃发展。目前主流的图神经网络处理方法相似&#xff0c;基本都离不开节点本身的表征和节点之间的相互关系&#xff08;即图的拓扑结构信息&#xff09;。然而&#xff0c;训练图…

51单片机的智能浇花系统【含proteus仿真+程序+报告+原理图】

1、主要功能 该系统由AT89C51单片机LCD1602显示模块DHT11温湿度模块DS1302时间模块继电器驱动水泵模块光敏传感器等模块构成。适用于智能浇花、自动浇花、智能盆栽等相似项目。 可实现基本功能: 1、LCD1602实时显示北京时间、土壤温湿度、光照强度等信息 2、DHT11采集温湿度信…

使用kafka_exporter监控Kafka

prometheus 监控 kafka 常见的有两种开源方案,一种是传统的部署 exporter 的方式,一种是通过 jmx 配置监控, 项目地址: kafka_exporter:https://github.com/danielqsj/kafka_exporterjmx_exporter:https://github.com/prometheus/jmx_exporter本文将采用kafka_exporter方…

数据库基础入门 — SQL

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

NextJS开发:解决React Hook useEffect has a missing dependency

NextJS编译出现如下错误,原因是在使用useEffect时&#xff0c;当我们将函数的声明放在useEffect函数外面时 或者使用useState定义的历史变量,会报警告 Warning: React Hook useEffect has a missing dependency解决方法&#xff1a; 1、逐个添加注释忽略警告 useEffect(() &…

网络安全项目简介

安全项⽬ 基线检查 更改缺省的账户检查Guest用户是否禁用密码复杂性密码长度账户口令的生存期口令重复次数口令认证失败次数口令到期提示域成员禁用更改机器账户密码限制匿名用户连接共享账户检查远程关机授权是否开启默认文件共享每个用户是否遵循最小权限原则adminstrator账…

数据结构与算法编程题7

单链表的相关操作(重点&#xff1a;头插法和尾插法) #include <iostream> using namespace std;typedef int Elemtype; #define ERROR 0; #define OK 1;typedef struct LNode {Elemtype data; //结点保存的数据struct LNode* next; //结构体指针 }LNode, * Link…

原来 TinyVue 组件库跨框架(Vue2、Vue3、React、Solid)是这样实现的?

本文由 TinyVue 组件库核心成员郑志超分享&#xff0c;首先分享了实现跨框架组件库的必要性&#xff0c;同时通过演示Demo和实际操作向我们介绍了如何实现一个跨框架的组件库。 前言 前端组件库跨框架是什么&#xff1f; 前端组件库跨框架是指在不同的前端框架&#xff08;如…

chrome 插件 Mobile simulator

谷歌浏览器插件Mobile simulator v3.8.2.0-2023-4-27&#xff08;做屏幕适应的前端工具&#xff09;-&#xff08;Chrome插件&#xff09;谷歌浏览器插件网 百度网盘&#xff1a;https://pan.baidu.com/s/1xVyny8CtlMjSchhTIlfRAA 提取码&#xff1a;cj5c

IT应用运维最常用指标

可用性&#xff08;Availability&#xff09; 系统或服务在特定时间范围内可用的百分比。 计算方式&#xff1a;&#xff08;总时间 - 不可用时间&#xff09;/ 总时间 * 100%。 参考值&#xff1a;99.9%。 应用范围&#xff1a;应用系统、网络设备。 故障率&#xff08;Fa…