java并发包:fork/join

2023-11-20

本文转载至:http://blog.csdn.net/a910626/article/details/51900967

Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

  我们再通过Fork和Join这两个单词来理解下Fork/Join框架,Fork就是把一个大任务切分为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结果。比如计算1+2+。。+10000,可以分割成10个子任务,每个子任务分别对1000个数进行求和,最终汇总这10个子任务的结果。Fork/Join的运行流程图如下:

  我们已经很清楚Fork/Join框架的需求了,那么我们可以思考一下,如果让我们来设计一个Fork/Join框架,该如何设计?这个思考有助于你理解Fork/Join框架的设计。

  第一步分割任务。首先我们需要有一个fork类来把大任务分割成子任务,有可能子任务还是很大,所以还需要不停的分割,直到分割出的子任务足够小。

  第二步执行任务并合并结果。分割的子任务分别放在双端队列里,然后几个启动线程分别从双端队列里获取任务执行。子任务执行完的结果都统一放在一个队列里,启动一个线程从队列里拿数据,然后合并这些数据。

Fork/Join使用两个类来完成以上两件事情:

ForkJoinTask:我们要使用ForkJoin框架,必须首先创建一个ForkJoin任务。它提供在任务中执行fork()和join()操作的机制,通常情况下我们不需要直接继承ForkJoinTask类,而只需要继承它的子类,Fork/Join框架提供了以下两个子类: 
RecursiveAction:用于没有返回结果的任务。 
RecursiveTask :用于有返回结果的任务。 
ForkJoinPool :ForkJoinTask需要通过ForkJoinPool来执行,任务分割出的子任务会添加到当前工作线程所维护的双端队列中,进入队列的头部。当一个工作线程的队列里暂时没有任务时,它会随机从其他工作线程的队列的尾部获取一个任务。

例子

/**
 * Created by niehongtao on 16/7/12.
 * join/fork结构
 */
public class CountTask extends RecursiveTask<Long> {
    private static final int THRESHOLD = 10000;
    private long start;
    private long end;

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

    @Override
    protected Long compute() {
        long sum = 0;
        boolean canCompute = (end - start) < THRESHOLD;
        if (canCompute) {
            for (long i = 0; i <= end; i++) {
                sum += i;
            }
        } else {
            // 分成100个小任务
            long step = (start + end)/100;
            ArrayList<CountTask> countTasks = new ArrayList<>();
            long pos = start;
            for (int i = 0; i < 100; i++) {
                long lastOne = pos + step;
                if (lastOne > end) {
                    lastOne = end;
                }
                CountTask countTask = new CountTask(pos, lastOne);
                pos += step + 1;
                countTasks.add(countTask);
                countTask.fork();
            }
            for (CountTask task : countTasks) {
                sum += task.join();
            }
        }
        return sum;
    }


    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        CountTask task = new CountTask(0, 200000L);
        ForkJoinTask<Long> result = forkJoinPool.submit(task);
        try {
            long res = result.get();
            System.out.print("sum=" + res);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java并发包:fork/join 的相关文章

  • (Java 基础知识) Java反射

    本篇文章依旧采用小例子来说明 因为我始终觉的 案例驱动是最好的 要不然只看理论的话 看了也不懂 不过建议大家在看完文章之后 在回过头去看看理论 会有更好的理解 下面开始正文 案例1 通过一个对象获得完整的包名和类名 1 2 3 4 5 6
  • Java线程:volatile关键字

    本文转载至 http lavasoft blog 51cto com 62575 222076 Java线程 volatile关键字 Java 语言包含两种内在的同步机制 同步块 或方法 和 volatile 变量 这两种机制的提出都是为了
  • Java 反射 与 主要API

    控制你的大脑 控制你的行为 你会得到更多 收获很多 文章目录 一 反射相关的主要API 二 代码例子演示 三 反射测试类 一 反射相关的主要API API 名称 代表含义 Java lang class 代表一个类 java lang re
  • Java线程:线程的交互

    本文转载至 http lavasoft blog 51cto com 62575 99157 线程交互是比较复杂的问题 SCJP要求不很基础 给定一个场景 编写代码来恰当使用等待 通知和通知所有线程 一 线程交互的基础知识 SCJP所要求的
  • (java 功能篇)java 读取Propety配置文件

    java效果代码 源代码 package com rf test import java io IOException import java io InputStream import java util Properties publi
  • java 阻塞模式与非阻塞模式

    TCP IP 阻塞模式与非阻塞模式 java view plain copy print package concurrentTest import java io BufferedReader import java io IOExcep
  • Java 生成随机数全数字方式

    生成9位随机数字 System out println int Math random 9 1 100000000 生成8位随机数字 System out println int Math random 9 1 10000000 生成6位随
  • Java线程:新特征-有返回值的线程

    本文转载至 http lavasoft blog 51cto com 62575 222082 在Java5之前 线程是没有返回值的 常常为了 有 返回值 破费周折 而且代码很不好写 或者干脆绕过这道坎 走别的路了 现在Java终于有可返回
  • Java 数组 初始化方式 和遍历方式

    Java 数组 初始化方式总结 第一种 静态初始化 所谓静态初始化 初始化时由程序员显式指定每个数组元素的初始值 有系统决定数组的长度 简单实例 String strArr 张三 李四 王五 第二种 动态初始化 所谓动态初始化 初始化时由程
  • Java线程:线程的调度-守护线程

    本文转载至 http lavasoft blog 51cto com 62575 221845 Java线程 线程的调度 守护线程 守护线程与普通线程写法上基本么啥区别 调用线程对象的方法setDaemon true 则可以将其设置为守护线
  • java 多线程 总结一

    首先讲一下进程和线程的区别 进程 每个进程都有独立的代码和数据空间 进程上下文 进程间的切换会有较大的开销 一个进程包含1 n个线程 线程 同一类线程共享代码和数据空间 每个线程有独立的运行栈和程序计数器 PC 线程切换开销小 线程和进程一
  • java并发包:生产者消费者模式

    本文转载至 http blog csdn net a910626 article details 51900974 生产者消费者模式是一个经典的多线程设计模式 它为多线程间的协作提供了良好的解决方案 在生产者消费者模式中 通常有两类线程 即
  • Java线程:线程状态的转换

    本文转载至 http lavasoft blog 51cto com 62575 99153 一 线程状态类型 1 新建状态 New 新创建了一个线程对象 2 就绪状态 Runnable 线程对象创建后 其他线程调用了该对象的start 方
  • java并发包:重入锁与Condition条件

    本文转载至 http blog csdn net a910626 article details 51900941 重入锁 这里介绍一下synchronized wait notify方法的替代品 或者说是增强版 重入锁 重入锁是可以完全替
  • java 多线程学习笔记之 线程同步

    在前面我们将了很多关于同步的问题 然而在现实中 需要线程之间的协作 比如说最经典的生产者 消费者模型 当队列满时 生产者需要等待队列有空间才能继续往里面放入商品 而在等待的期间内 生产者必须释放对临界资源 即队列 的占用权 因为生产者如果不
  • (Java基础知识) 几种Java任务调度比较

    前言 任务调度是指基于给定时间点 给定时间间隔或者给定执行次数自动执行任务 本文由浅入深介绍四种任务调度的 Java 实现 Timer ScheduledExecutor 开源工具包 Quartz 开源工具包 JCronTab 此外 为结合
  • (Java 基础知识) Java 正则表达式

    一 概述 正则表达式是Java处理字符串 文本的重要工具 Java对正则表达式的处理集中在以下两个两个类 java util regex Matcher 模式类 用来表示一个编译过的正则表达式 java util regex Pattern
  • Java线程:线程的调度-休眠

    本文转载至 http lavasoft blog 51cto com 62575 221790 Java线程 线程的调度 休眠 Java线程调度是Java多线程的核心 只有良好的调度 才能充分发挥系统的性能 提高程序的执行效率 这里要明确的
  • 线程管理之Thread类相关方法简介

    CurrentThread 静态方法 currentThread 方法可返回代码段正在被那个线程调用的信息 简单案列 打印main 方法 正在被那个线程调用 package com zzg thread import com zzg obj
  • (java 基础知识) Java打印---javax.print

    package com print import java io import javax print import javax print attribute import javax print attribute standard p

随机推荐

  • node中间件是什么意思?

    node中间件是什么意思 2020 09 11 16 11 17分类 常见问题 Node js答疑阅读 1757 评论 0 中间件是一种独立的系统软件或服务程序 分布式应用软件借助这种软件在不同的技术之间共享资源 中间件位于客户机 服务器的
  • Spark SQL 项目:实现各区域热门商品前N统计

    一 需求1 1 需求简介这里的热门商品是从点击量的维度来看的 计算各个区域前三大热门商品 并备注上每个商品在主要城市中的分布比例 超过两个城市用其他显示 1 2 思路分析使用 sql 来完成 碰到复杂的需求 可以使用 udf 或 udaf查
  • 四位均衡磨损格雷码

    什么是均衡磨损格雷码 均衡磨损格雷码是一种与标准格雷码具有相同的迭代后只变化一个位的特性 但每一个数位变化的次数相近的编码 为什么要均衡磨损 由于继电器输出PLC比晶体管输出PLC具有更好的可靠性 如果用继电器输出的PLC代替晶体管输出PL
  • 从0开始用shell写一个tomcat日志清理脚本

    一 目的 tomcat日志随着时间的流逝会越来越大 虽然我们可以使用cronolog对tomcat输出的日志根据日期进行切割 但是日子一长 进到logs 文件夹下都是密密麻麻的日志 不好查看也浪费了大量的空间 故本文的目的是编写一个脚本 能
  • linux 0.11 int80实现,Linux0.11内核--系统中断处理程序int 0x80实现原理

    extern int sys setup 系统启动初始化设置函数 kernel blk drv hd c 71 extern int sys exit 程序退出 kernel exit c 137 extern int sys fork 创
  • 神经网络学习小记录68——Tensorflow2版 Vision Transformer(VIT)模型的复现详解

    神经网络学习小记录68 Tensorflow2版 Vision Transformer VIT 模型的复现详解 学习前言 什么是Vision Transformer VIT 代码下载 Vision Transforme的实现思路 一 整体结
  • 尘技-教你如何造安全相关文章

    介绍 写文章不仅仅能够总结自己的知识 还能为他人提供帮助 以及 我为自己代言 稿费 曝光度等等 如何能有思路的制造文章 下面由我慢慢道来 造文种类 造文可以分为总结类 创新类 实录类 见解类 工具分享类等等 每种类型的文章 都有自己的造文套
  • JDK自带JVM监控jvisualvm.exe 观察JVM内应用程序

    无论在测试环境还是在生产环境 我们都想知道程序在JVM中是否正常运行 除了使用第三方的一些工具 最直接的就是使用JDK自带的jvisualvm exe 系统主界面操作 JVM提供了本地的JVM监控 远程的JMX监控和快照服务 VM示例 Vi
  • 本地CPU部署运行ChatGLM2-6B模型

    1 前期准备 需要下载模型文件 2 部署过程及碰到的问题 1 编译安装python 3 8 13 Asianux release 7 6 18 gcc 4 8 5 按运行的要求需要安装torch的 gt 2 0 因此安装了torch的2 0
  • 网站打不开如何解决?教你4个方法搞定它!

    网站打不开如何解决 教你4个方法搞定它 网站如果打不开了 会影响正常的使用 并且对于SEO关键词排名还是有影响的 那么网站打不开如何解决 可能对于不懂技术的客户来说这是个着急的问题 突然发现自己的网站打不开了 不知所措 如果再遇到这样的问题
  • 记录一次elasticsearch挂掉之后无法启动 kibana Status: Red -分析过程

    记录一次elasticsearch挂掉之后无法启动 kibana Status Red 分析过程 现象 现象一 kibana Status Red 现象二 elasticsearch 集群挂掉 现象三 elasticsearch 重启 检查
  • 群晖DSM7.2 系统Web Station配置NodeJS类型网站访问方法

    平时也不怎么更新系统 最近因为用SH方式架设运行的NodeJS网站Express用着有点小问题 其中细节还需要测试原因 在更新了一堆套件之后 又看到了 系统更新的小细点 一时手残便点了更新 然后就来到了DSM 7 2 64570 Updat
  • 2014年1月30日-2月6日,(共4小时,剩4682小时)

    过年期间 初五学了3小时 初七晚上1小时 共4小时 受打击很大 好好努力吧
  • 常用表单正则表达式

    校验 大小写字母 汉字 export const verifyCheEng a zA Z p sc Han gu 校验 数字 大小写字母 汉字 export const verifyCheEngNum a zA Z0 9 p sc Han
  • LZW编码

    LZW Lempel Ziv Welch 编码又称字串表编码 是Welch将Lemple和Ziv所提出来的无损压缩技术改进后的压缩方法 GIF图像文件采用的是一种改良的LZW压缩算法 通常称为GIF LZW压缩算法 下面简要介绍GIF LZ
  • 实测视频!为什么独立比贴片IMU更适合智能驾驶?

    在汽车智能化这场行业变革中 作为智能驾驶的标配 高精度定位系统已成L2级及以上智能驾驶 照进现实 进程中四两拨千斤的存在 惯性测量单元IMU因其工作不依赖包括卫星在内的外界信号 已是智能汽车高精度定位系统的核心元器件 然而行业对于IMU应如
  • iOS 架构组件:让你的 TableView 优雅起来

    看什么看 点我呀 全栈程序员 免费入门到精通 作者丨indulge inhttps www jianshu com p 7db73489ad99 GitHub 地址 https github com indulgeIn YBHandyTab
  • iOS代码混淆初探

    iOS代码混淆初探 在没有对应用的代码做过特殊处理的情况下 一般应用的代码中的类名和方法都是明文的 在逆向分析中 通过class dump获取MachO可执行文件中的所有类 定义的方法和属性 就能很快的从名字入手猜到这个方法是做什么用的 所
  • 如何查看MySQL的版本?

    原文地址 http blog csdn net lamp yang 3533 article details 52266320 查看MySQL的版本 主要有以下几个方法 1 没有连接到MySQL服务器 就想查看MySQL的版本 打开cmd
  • java并发包:fork/join

    本文转载至 http blog csdn net a910626 article details 51900967 Fork Join框架是Java7提供了的一个用于并行执行任务的框架 是一个把大任务分割成若干个小任务 最终汇总每个小任务结