"分而治之"的一个有效的处理大数据的方法,著名的MapReduce就是采用这种分而治之的思路,简单点生活如果要处理的1000个数据,但是我们不具备处理1000个数据的能量,可以处理10个数据,可以把这个1000个数据分阶段处理100次,每次处理10个,吧100次的处理结果进行合成,形成最后的1000个数据的处理结果

把一个大任务调用fork()方法分解为若干个小任务,把小任务的处理结果进行join()合并为大任务的结果


系统对ForkJoinPool线程池进行了优化,提交的任务数量与线程的数量不一定是一对一的关系,在多数情况下,一个物理线程实际上需要处理多个逻辑任务


ForkJoinPool线程池中最常用的方法是:

ForkJoinTask submit(ForkJoinTask task) 向线程池提交一个ForkJoinTask任务,ForkJoinTask任务支持fork()分解与join等待的任务,ForkJoinTask有两个重要的子类:RecursiveAction和RecursiveTask

RecursiveAction任务没有返回值,RecursiveTask任务可以带返回值

dome


package com.dome.threadpool;import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;/*** @author qb* @version 1.0* @Description* 演示 ForkJoinPool线程池的使用* @date 2021/3/12 16:49*/
public class Test09 {//计算数列的和,需要返回结果,可以定义任务继承RecursiveTaskprivate static class CountTask extends RecursiveTask<Long>{private static final int THRESHOLD = 10000; //数据规模的阈值,允许计算10000个数内的和,超过failed阈值的数列就分解//每次吧大任务分解为100个小任务private static final int TASKNUMBER = 100;private long start;  //计算数列的开始位置private long end; //结束位置public CountTask(long start, long end) {this.start = start;this.end = end;}@Overrideprotected Long compute() {long sum = 0; //保存计算的结果//判断任务是否需要继续分解,如果当前数列end与start范围的超过阈值THRESHOLD,就继续分解if(end - start < THRESHOLD){//小于就直接计算for (long i = start; i <= end; i++) {sum += i;}}else{//超过阈值,继续分解//约定每次分解为100个小任务,就计算每个任务的计算量long step = (start + end ) /TASKNUMBER;//start = 0; end=200000; step = 2000;//如果计算[0,200000] 把该范围内的数列费结为100个小任务,每个任务就计算2000个数即可//如果任务划分的层次很深THRESHOLD阈值太小,每个人的计算量很小,这个层次划分就会很深//1.系统内的线程数量会越积越多,导致系统性能下降//2.分解任务过多,层次过深,方法调用过多可能会导致栈溢出//创建一个存储任务的集合ArrayList<CountTask> subTaskList = new ArrayList<>();long pos = start;//每个任务的起始位置for (int i = 0; i < TASKNUMBER; i++) {long lastOne = pos +step; //没个任务的结束任务//调整最后一个任务的结束位置if(lastOne > end){lastOne = end;}CountTask countTask = new CountTask(pos,lastOne);//把任务添加到集合中subTaskList.add(countTask);//调用fork()提交任务countTask.fork();//调整下个任务的起始位置pos += step+1;}//等待所有子任务结束后合并结果for(CountTask task : subTaskList){sum += task.join(); //join一直等待子任务执行完毕,}}return sum;}}public static void main(String[] args) {//创建ForkJoinPool线程池ForkJoinPool forkJoinPool = new ForkJoinPool();//创建大的任务CountTask task = new CountTask(0,200000L);//把大任务提交线程池ForkJoinTask<Long> r = forkJoinPool.submit(task);try {Long res =  r.get();System.out.println("结果为:"+res);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}long s = 0L;for (int i = 0; i <= 200000; i++) {s += i;}System.out.println("s:"+s);}}

多线程之 ForkJoinool线程池(二十四)相关推荐

  1. 【二十四】springboot使用EasyExcel和线程池实现多线程导入Excel数据

      springboot篇章整体栏目:  [一]springboot整合swagger(超详细 [二]springboot整合swagger(自定义)(超详细) [三]springboot整合toke ...

  2. 侠客岛--多线程系列之线程池(十二)

    文章目录 线程池原理 一.为什么要使用线程池 二.线程池的原理 1. ThreadPoolExecutor提供的构造方法 1.1 构造方法 1.2 构造方法参数 2. ThreadPoolExecut ...

  3. 多线程教程(二十四)CAS+volatile

    多线程教程(二十四)CAS+volatile 获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰. 它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量 ...

  4. Java多线程系列--“JUC线程池”06之 Callable和Future

    转载自  Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...

  5. 第十章_多线程(2)_线程池原子性并发工具类

    目录 一.线程池 1 - 线程状态 2 - 线程池 3 - Executors线程池 二.Volatile 三.原子性 四.并发工具类 1 - 并发工具类-Hashtable 2 - 并发工具类-Co ...

  6. 大话设计模式笔记(二十一、二十二、二十三、二十四、二十五、二十六)

    二十一.单例模式(Singleton) 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 1.通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法就是 ...

  7. J2EE进阶(二十四)JBoss Web和 Tomcat的区别

    J2EE进阶(二十四)JBoss Web和 Tomcat的区别 在Web2.0的浪潮中,各种页面技术和框架不断涌现,为服务器端的基础架构提出了更高的稳定性和可扩展性的要求.近年来,作为开源中间件的全球 ...

  8. 异常处理程序和软件异常——Windows核心编程学习手札之二十四

    异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...

  9. linux下c语言线程传参数,【linux】C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0...

    C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0 本贴问题,之前已经提问过一次,当时已经解决了,原贴在这里https://segmentfault.com/q/1 ...

最新文章

  1. NetBeans 时事通讯(刊号 # 106 - Jun 17, 2010)
  2. 如何辨别二逼、文艺互联网公司?
  3. 【错误记录】Android Studio 中查看 Gradle 配置的方法源码 ( 配置 gradle-wrapper.properties 中版本为 gradle-x.x.x-all.zip )
  4. 2ASK和2FSK相干解调误码率仿真matlab
  5. 不会这些基础命令,白做运维了
  6. C# ini文件读写函数
  7. 在.NET中使用DiagnosticSource
  8. 只需3步,即可将你的Chromium Edge 浏览器设置成中文
  9. 另类架构师:在国企涂肥皂水、考研被调剂、在阿里跟十八罗汉当同事……
  10. python label显示图片_高大上的YOLOV3对象检测算法,使用python也可轻松实现
  11. python程序设计试题库_最新《Python程序设计》试题库资料
  12. 人工智能与机器学习的关系---人工智能工作笔记0013
  13. 【数据库实验】《小型MIS的开发》PyQt5 开发 民航票务管理系统
  14. centos7安装rabbitmq_rabbitmq v3.7.16安装部署文档
  15. 【EMNLP2020】一种多层对多层的BERT蒸馏方法
  16. 吴恩达深度学习——机器学习策略(二)
  17. IS-IS快速收敛调优(一)——IS-IS收敛机制
  18. 大数据第三季--sqoop(day1)-徐培成-专题视频课程
  19. APP中如何判断手机类型
  20. BZOJ.4453.cys就是要拿英魂!(后缀数组 单调栈)

热门文章

  1. 客户最佳实践 | All in企业微信,苏州吴中维多利亚美容医院让每位员工成为“美丽管家”!
  2. [ROS2] map_server加载地图文件的三种模式
  3. 你想要知道的Python日期格式化知识都在这
  4. java中的比较方法
  5. 管理学计算机要求,[管理学]计算机第一章.ppt
  6. 基于STM32L431设计的云端绿化管理系统(ESP8266+腾讯物联网云平台)
  7. 图形学_二维图形的剪裁_Sutherland-Hodgeman_Cohen—Sutherland
  8. 欢迎进入半颗心脏博客导航一站式搜索(所有博客的汇总帖)
  9. vuex-module-decorators装饰器的使用
  10. 海康摄像头电子防抖和3D放大冲突