多线程之 ForkJoinool线程池(二十四)
"分而治之"的一个有效的处理大数据的方法,著名的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线程池(二十四)相关推荐
- 【二十四】springboot使用EasyExcel和线程池实现多线程导入Excel数据
springboot篇章整体栏目: [一]springboot整合swagger(超详细 [二]springboot整合swagger(自定义)(超详细) [三]springboot整合toke ...
- 侠客岛--多线程系列之线程池(十二)
文章目录 线程池原理 一.为什么要使用线程池 二.线程池的原理 1. ThreadPoolExecutor提供的构造方法 1.1 构造方法 1.2 构造方法参数 2. ThreadPoolExecut ...
- 多线程教程(二十四)CAS+volatile
多线程教程(二十四)CAS+volatile 获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰. 它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量 ...
- Java多线程系列--“JUC线程池”06之 Callable和Future
转载自 Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...
- 第十章_多线程(2)_线程池原子性并发工具类
目录 一.线程池 1 - 线程状态 2 - 线程池 3 - Executors线程池 二.Volatile 三.原子性 四.并发工具类 1 - 并发工具类-Hashtable 2 - 并发工具类-Co ...
- 大话设计模式笔记(二十一、二十二、二十三、二十四、二十五、二十六)
二十一.单例模式(Singleton) 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 1.通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法就是 ...
- J2EE进阶(二十四)JBoss Web和 Tomcat的区别
J2EE进阶(二十四)JBoss Web和 Tomcat的区别 在Web2.0的浪潮中,各种页面技术和框架不断涌现,为服务器端的基础架构提出了更高的稳定性和可扩展性的要求.近年来,作为开源中间件的全球 ...
- 异常处理程序和软件异常——Windows核心编程学习手札之二十四
异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...
- linux下c语言线程传参数,【linux】C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0...
C语言多线程中运行线程池,在线程池中运行线程池,,传递的结构体参数值为空/NULL/0 本贴问题,之前已经提问过一次,当时已经解决了,原贴在这里https://segmentfault.com/q/1 ...
最新文章
- NetBeans 时事通讯(刊号 # 106 - Jun 17, 2010)
- 如何辨别二逼、文艺互联网公司?
- 【错误记录】Android Studio 中查看 Gradle 配置的方法源码 ( 配置 gradle-wrapper.properties 中版本为 gradle-x.x.x-all.zip )
- 2ASK和2FSK相干解调误码率仿真matlab
- 不会这些基础命令,白做运维了
- C# ini文件读写函数
- 在.NET中使用DiagnosticSource
- 只需3步,即可将你的Chromium Edge 浏览器设置成中文
- 另类架构师:在国企涂肥皂水、考研被调剂、在阿里跟十八罗汉当同事……
- python label显示图片_高大上的YOLOV3对象检测算法,使用python也可轻松实现
- python程序设计试题库_最新《Python程序设计》试题库资料
- 人工智能与机器学习的关系---人工智能工作笔记0013
- 【数据库实验】《小型MIS的开发》PyQt5 开发 民航票务管理系统
- centos7安装rabbitmq_rabbitmq v3.7.16安装部署文档
- 【EMNLP2020】一种多层对多层的BERT蒸馏方法
- 吴恩达深度学习——机器学习策略(二)
- IS-IS快速收敛调优(一)——IS-IS收敛机制
- 大数据第三季--sqoop(day1)-徐培成-专题视频课程
- APP中如何判断手机类型
- BZOJ.4453.cys就是要拿英魂!(后缀数组 单调栈)
热门文章
- 客户最佳实践 | All in企业微信,苏州吴中维多利亚美容医院让每位员工成为“美丽管家”!
- [ROS2] map_server加载地图文件的三种模式
- 你想要知道的Python日期格式化知识都在这
- java中的比较方法
- 管理学计算机要求,[管理学]计算机第一章.ppt
- 基于STM32L431设计的云端绿化管理系统(ESP8266+腾讯物联网云平台)
- 图形学_二维图形的剪裁_Sutherland-Hodgeman_Cohen—Sutherland
- 欢迎进入半颗心脏博客导航一站式搜索(所有博客的汇总帖)
- vuex-module-decorators装饰器的使用
- 海康摄像头电子防抖和3D放大冲突