分享Fork/Join经典案例

news2024/11/27 6:31:51

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。
个人IP:shigen

在上一篇的文章java 多线程+分治求和,太牛了的文章中,提到了forkjoin,在一番了解之后,发现这个forkjoin基本上和线程池差不多

Fork/Join框架的核心思想是将大任务拆分成若干个小任务(Fork),然后并行执行这些小任务,最后将它们的结果合并(Join)。这样可以充分利用多核处理器的性能,提高任务的执行效率。

在一些论坛上网友也回复:大数据的认识这个。也是啊,没准吊打我的面试官就是搞大数据的呢。正常的Java开发,哪来的这么多需要运算的任务,大部分都是IO型的任务,参考文章Excel导入导出百万级数据优化。

写了一点代码测试了一下效果,选用的还是经典的大序列求和案例:

public class SumCalculator extends RecursiveTask<Long> {

    private static final long serialVersionUID = 1L;
    // 阈值,超过这个值则拆分任务
    private static final long THRESHOLD = 10000;
    private final long start;
    private final long end;

    public SumCalculator(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long length = end - start;
        if (length <= THRESHOLD) {
            return computeSequentially();
        }
        long middle = (start + end) >>> 1;
        SumCalculator leftTask = new SumCalculator(start, middle);
        SumCalculator rightTask = new SumCalculator(middle + 1, end);
        // 拆分左边任务
        leftTask.fork();
        // 拆分右边任务
        rightTask.fork();
        // 合并并返回结果
        return leftTask.join() + rightTask.join();
    }

    private long computeSequentially() {
        long sum = 0;
        for (long i = start; i <= end; i++) {
            sum += i;
        }
        return sum;
    }

    public static void main(String[] args) {
        long start = 1;
        long end = 1_0000_0000;
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        long result = forkJoinPool.invoke(new SumCalculator(start, end));
        stopWatch.stop();
        System.out.println("Sum of " + start + " to " + end + " = " + result);
        System.out.println("Elapsed time: " + stopWatch.getTotalTimeMillis() + " ms");
    }
}

运行时间我们来对比一下:

forkjoin运行时间

普通线程池:

普通线程池

多次运行后发现:时间在100ms-300ms之间波动。

总的来说,fork/join的效率至少要比普通线程池提交任务运行耗时减少50%左右。

最后,借助魔法和个人理解,来一波总结:

Fork/Join适用场景:

  1. 递归任务:Fork/Join框架特别适用于递归式的任务,例如归并排序、快速排序、求和等。
  2. 任务可以被拆分成独立子任务:任务之间不存在依赖关系,可以独立执行,这样才能充分发挥并行执行的优势。
  3. 任务执行时间较长:如果任务执行时间过短,切分和合并的开销可能会超过执行时间,得不偿失。

注意事项:

  1. 合适的任务粒度:需要根据具体情况确定合适的任务拆分粒度,避免任务过小导致拆分和合并的开销过大。
  2. 避免共享可变状态:并行执行的任务之间应避免共享可变状态,如果必须共享状态,需要采用线程安全的方式进行处理。
  3. 避免死锁和性能问题:在使用Fork/Join框架时,要注意避免死锁和性能问题,合理设计任务拆分和合并的逻辑。
  4. 使用合适的线程池:Fork/Join框架底层使用了工作窃取(Work Stealing)算法,因此可以使用默认的ForkJoinPool,也可以根据需要创建自定义的线程池。

总的来说,Fork/Join框架适用于需要并行执行递归式任务且任务之间不存在太多依赖关系的情况,能够充分利用多核处理器的性能,提高任务的执行效率。

好了,底层原理还是比较复杂,推荐观看视频:6.8 并发编程之ForkJoin工作原理分析。搞不明白,在这里就不深入分析底层原理了。

*与shigen一起,每天不一样!

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

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

相关文章

【JVM】常见的JVM参数

常见的JVM参数 ◼ 参数1 &#xff1a; -Xmx 和 –Xms-Xmx 参数设置的是最大堆内存&#xff0c;但是由于程序是运行在服务器或者容器上&#xff0c;计算可用内存时&#xff0c;要将元空间、操作系统、 其它软件占用的内存排除掉。 案例&#xff1a; 服务器内存4G&#xff0c;…

【Leetcode每日一题】 递归 - 二叉树剪枝(难度⭐⭐)(50)

1. 题目解析 题目链接&#xff1a;814. 二叉树剪枝 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 想象一下&#xff0c;你有一堆层层叠叠的积木&#xff0c;你想从底部开始&#xff0c;把那些标记为0的积木拿走。如…

如何在Flutter应用中配置ipa Guard进行混淆

在移动应用开发中&#xff0c;保护应用代码安全至关重要。Flutter 提供了简单易用的混淆工具&#xff0c;帮助开发者在构建 release 版本应用时有效保护代码。本文将介绍如何在 Flutter 应用中使用混淆&#xff0c;并提供了相关的操作步骤和注意事项。 &#x1f4dd; 摘要 本…

【行业资讯】AI算力的需求推动光模块行业快速迭代

近期&#xff0c;由OpenAI发布的人工智能文生视频大模型Sora再次引起了不小的轰动&#xff0c;继ChatGPT之后&#xff0c;Sora的推出让AIGC&#xff08;生成式人工智能&#xff09;再度成为行业焦点&#xff0c;AI大模型的快速迭代升级对网络架构提出了更高要求&#xff0c;推动…

GlusterFS分布式存储

目录 前言 一、GlusterFS分布式存储概述 1、GFS概念 2、GFS特点 3、GFS术语 4、GFS构成 5、GFS工作流程 6、后端存储如何定位文件 7、GlusterFs的卷类型 7.1 Distributed Volume&#xff08;分布式卷&#xff09; 7.2 Striped Volume&#xff08;条带卷&#xff09…

项目实战 | 使用python分析Excel销售数据(用groupby)

项目实战 | 使用python分析Excel销售数据 本文目录&#xff1a; 零、00时光宝盒 一、提出问题 二、理解数据 2.1、安装python读取excel文件的库 2.2、查看excel表的字段名和前几行记录 2.3、查看excel表结构 2.4、查看索引 2.5、查看每一列的列表头内容 2.6、查看每一…

SpringBoot中application.yml引入多个YML文件

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 首先,你要了解SpringBoot配置文件加载顺序,加载位置(代码内,Nacos等)…

[数据结构]栈和队列结构的简单制作

一、栈 1.1栈的概念以及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。 栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原…

yolov7的改进工地安全帽佩戴检测系统-协同双注意力机制CDAM2(教程+代码)

研究的背景和意义 随着工业化和城市化的快速发展&#xff0c;建筑工地的安全问题日益凸显。在建筑工地中&#xff0c;工人的安全是至关重要的&#xff0c;而工地安全帽的佩戴是保障工人安全的重要措施之一。然而&#xff0c;由于工地环境复杂多变&#xff0c;工人的佩戴情况往…

网络安全之权限维持那点事

权限维持 一旦黑客成功地入侵了目标系统&#xff0c;他们通常会尝试保持对系统的持久访问权&#xff0c;以便继续执行恶意活动&#xff0c;如窃取敏感数据、植入恶意软件、破坏系统功能等。 权限维持的过程可能包括以下几个方面&#xff1a; 后门植入&#xff1a;黑客可能会在…

蓝桥杯单片机要点——第十二届省赛(含代码)

题目&#xff1a; 用到的模块&#xff1a; LED单个点亮&#xff08;建议用sbit&#xff0c;文件开头定义单个引脚&#xff09; 数码管动态显示 矩阵键盘 ds18b20&#xff0c;用到onewire.c DAC转化&#xff08;步骤见文章末尾的易错点&#xff09;&#xff0c;用到iic.c m…

一本书了解AI的下一个风口:AI Agent

在数字化浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动现代社会前进的强劲引擎。 从智能手机的智能助手到自动驾驶汽车的精准导航&#xff0c;AI技术的应用已经渗透到生活的方方面面。 随着技术的飞速发展&#xff0c;我们正站在一个新的转折点上&#xff…

Playwright安装和基本使用(ui/web自动化)

1.简介 Playwright是2021年微软开源的一个项目「playwright-python」。针对 Python 语言的纯自动化工具&#xff0c;它可以通过单个API自动执行 Chromium&#xff0c;Firefox 和 WebKit 浏览器&#xff0c;同时支持以无头模式、有头模式运行。 Playwright&#xff08;Git&…

美国CPC认证是什么认证

美国CPC认证是一种针对儿童产品的认证&#xff0c;旨在确保这些产品的安全性。CPC全称为Consumer Product Certification&#xff0c;即消费品认证&#xff0c;是美国消费品安全委员会&#xff08;CPSC&#xff09;所推行的一种自愿性认证制度。通过CPC认证的产品&#xff0c;意…

人证比对接口在游戏行业的作用

人证比对接口又叫实人认证接口、人脸身份证比对接口、人脸实名认证接口&#xff0c;这个接口在很多行业都有重大作用&#xff0c;特别是确认当前用户信息至关重要。今天我们来聊一聊实人认证接口在游戏行业的作用。 今天为什么聊这个话题呢&#xff0c;主要就是最近热搜都被杭…

AR远程空间标注Vuforia+WebRTC音视频通话和空间标注功能

AR远程空间标注VuforiaWebRTC音视频通话和空间标注功能 视频学习地址&#xff1a;https://www.bilibili.com/video/BV1ZT4y187mG/?vd_sourcefc4b6cdd80b58c93a280fd74c37aadbf

LeetCode110:平衡二叉树

题目描述 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 解题思想 使用递归依次计算左子树的高度和右子树的高度 代码 class Solution { public:int height(TreeNode* node) {if (node nullptr) return 0;int leftT height(node->left);if (leftT -1) return -1;…

武汉星起航:亚马逊助力中国卖家拓展全球市场,实现品牌价值最大化

亚马逊&#xff0c;作为全球电商的领军平台&#xff0c;不仅为消费者提供了丰富的购物选择&#xff0c;同时也为中国卖家带来了前所未有的益处和在中国市场的巨大优势。 亚马逊为中国卖家提供了一个全球化的销售平台。这个平台不仅连接了中国与世界的消费者&#xff0c;还为中…

标准C库文件操作

open 系列API 和 fopen系列API的区别 1.来源: -open 是UNIX系统调用函数(包括LINUX系统)&#xff0c;返回的是文件描述符 -fopen是ANSIC标准的C语言库函数&#xff0c;在不同系统重调用不同内核的API 2.移植性: fopen 是C标准函数&#xff0c;具有良好的移植性&#xff1b; 而…

Vue 移动端(H5)项目怎么实现页面缓存(即列表页面进入详情返回后列表页面缓存且还原页面滚动条位置)keep-alive简单使用

一、需求 产品要求&#xff1a;Vue移动端项目进入列表页&#xff0c;列表页需要刷新&#xff0c;而从详情页返回列表页&#xff0c;列表页则需要缓存并且还原页面滚动条位置 二、实现思路 1、使用Vue中的keep-alive组件&#xff0c;keep-alive提供了路由缓存功能 2、因为我项…