一、分而治之

严格来讲,分而治之不算一种模式,而是一种思想。它可以将一个大任务拆解为若干个小任务并行执行,提高系统吞吐量。主要讲两个场景,Master-Worker 模式,ForkJoin 线程池。

ForkJoin 线程池是Jdk7之后引入的一个并行执行任务的框架。其核心思想是将任务分割为子任务,有可能子任务还是很大,还需要进一步拆解,最终得到足够小的任务。将分割出来的子任务放入双端队列中,然后几个启动线程从双端队列中获取任务执行。子任务执行的结果放到一个队列里,另起线程从队列中获取数据,合并结果。

二、ForkJoin 与传统线程池的区别

采用 “工作窃取”模式(work-stealing):当执行新的任务时,它可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。 相较于一般的线程池,ForkJoin 的优势体现在对其中包含的任务的处理方式上。在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态。而 ForkJoin,如果某个子问题由于等待另外一个子问题的完成而无法继续运行,那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行。这种方式减少了线程的等待时间,提高了性能。

三、案例

计算从 0 到 100L 的累加求和。CountTask 继承自 RecursiveTask,可以携带返回值。每次分解大任务,简单的将任务划分为 10 个等规模的小任务,并使用 fork() 提交子任务。在子任务中通过 THRESHOLD(门槛) 设置子任务分解的阈值,如果当前需要求和的总数大于 THRESHOLD,则子任务需要再次分解,如果子任务可以直接执行,则进行求和操作,返回结果。最终等待所有的子任务执行完毕,对所有结果求和。

public class CountTask extends RecursiveTask<Long> {//任务分解的阈值private static final int THRESHOLD = 11;private long start;private long end;public CountTask(long start, long end) {this.start = start;this.end = end;}public Long compute() {long sum = 0;boolean canCompute = (end - start) < THRESHOLD;if (canCompute) {for (long i = start; i <= end; i++) {sum += i;}} else {//分成100个小任务long step = (start + end) / 10;ArrayList<CountTask> subTasks = new ArrayList<CountTask>();long pos = start;for (int i = 0; i < 10; i++) {long lastOne = pos + step;if (lastOne > end) {lastOne = end;}CountTask subTask = new CountTask(pos, lastOne);pos += step + 1;//将子任务推向线程池subTasks.add(subTask);subTask.fork();}for (CountTask task : subTasks) {//对结果进行joinsum += task.join();}}return sum;}public static void main(String[] args) throws ExecutionException, InterruptedException {ForkJoinPool pool = new ForkJoinPool();// 累加求和 0 -> 100LCountTask task = new CountTask(0, 100L);ForkJoinTask<Long> result = pool.submit(task);System.out.println("sum result : " + result.get());}
}

ForkJoin 线程池使用一个无锁的栈来管理空闲线程,如果一个工作线程暂时取不到可用的任务,则可能被挂起。挂起的线程将被压入由线程池维护的栈中,待将来有任务可用时,再从栈中唤醒这些线程。Java8 的并行流就是基于 ForkJoin,并进行了优化。

ForkJoin 线程池相关推荐

  1. ForkJoin线程池

    一.分而治之 严格来讲,分而治之不算一种模式,而是一种思想.它可以将一个大任务拆解为若干个小任务并行执行,提高系统吞吐量.主要讲两个场景,Master-Worker 模式,ForkJoin 线程池. ...

  2. fork/join和线程池_从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存...

    fork/join和线程池 问题: 启用了Spring且其范围设置为Request的缓存需要由不在请求范围内的singleton bean访问. 解: Spring使您能够创建缓存,该缓存为请求范围保 ...

  3. 从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存

    问题: 启用了Spring且将范围设置为Request的缓存需要由不在请求范围内的singleton bean访问. 解: Spring使您能够创建缓存,该缓存为请求范围保留数据. 例如 import ...

  4. 浅谈Java锁,与JUC的常用类,集合安全类,常用辅助类,读写锁,阻塞队列,线程池,ForkJoin,volatile,单例模式不安全,CAS,各种锁

    浅谈JUC的常用类 JUC就是java.util.concurrent-包下的类 回顾多线程 Java默认有几个线程? 2 个 mian.GC Java 真的可以开启线程吗? 开不了,点击源码得知:本 ...

  5. 多线程与高并发(七):详解线程池 - 自定义线程池,JDK自带线程池,ForkJoin,源码解析等

    Executor 接口关系 Callable:类似于Runnable,但是可以有返回值 Future:存储将来执行的结果.Callable被执行完之后的结果,被封装到Future里面. Future ...

  6. c++ 线程池_基础篇:高并发一瞥,线程和线程池的总结

    进程是执行程序的实体,拥有独属的进程空间(内存.磁盘等).而线程是进程的一个执行流程,一个进程可包含多个线程,共享该进程的所有资源:代码段,数据段(全局变量和静态变量),堆存储:但每个线程拥有自己的执 ...

  7. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  8. 线程池参数详解_java中常见的六种线程池详解

    之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的六种线程池如 ...

  9. 线程与线程池(一条龙详解)

    一:前言 一个问题引出的学习笔记 并发类库提供的线程池实现有哪些? 其实Executors已经为我们封装好了 4 种常见的功能线程池,如下: 定长线程池(FixedThreadPool) 定时线程池( ...

最新文章

  1. MySQL中如何插入数据(DML)
  2. Flutter 中的Error的捕获及处理
  3. 我是如何学习写一个操作系统(二):操作系统的启动之Bootloader
  4. 线性代数三之状压DP的矩阵加速——Quad Tiling,Bus公交线路
  5. [Silverlight入门系列]使用MVVM模式(7):ViewModel的INotifyPropertyChanged接口实现
  6. 如何把开源项目发布到Jcenter
  7. 面向初学者的带MVC API的Angular Js Table CRUD MSSQL
  8. vue 指令 v-on 事件修饰符-鼠标事件-什么是事件冒泡
  9. 求解数独难题, Sudoku问题(回溯)
  10. Druid 简介,架构,部署,python连接,hue链接druid
  11. Entity Framework 与 面向对象
  12. Django笔记 —— 模型高级进阶
  13. 只需一个设置命令隐藏 MacBook Pro 浏海
  14. 数组越界也可以这么巧~~~
  15. 国内外有哪些有前景的 AR VR公司?
  16. linux e1000内核源码,linux下e1000网卡奇怪现象
  17. 【高数】Abel定理,幂级数的和收敛半径,不同幂级数收敛半径的比较,缺项幂级数的解法
  18. Effie 致创作路上的独行者:动静相宜
  19. 移植vsftpd FTP服务器到ARM-Linux系统
  20. 通用的综合大数据数据可视化展示html页面源码

热门文章

  1. 针对卖家的API-----淘宝/天猫卖家店铺添加宝贝 API 返回值说明
  2. 8张设计师手绘图,详解全屋装修开关插座布局,太实用了!
  3. PS基础-通道、蒙版
  4. python中bytearray函数_Python内置函数(7)——bytearray
  5. 孤立森林(isolation):一个最频繁使用的异常检测算法
  6. vs2008 MFC使用DataGrid控件绑定数据库
  7. db2 删除索引_数据库三种删除方式
  8. 苹果无线笔记本怎么连不上win服务器,老司机还原苹果笔记本电脑连接不上wifi该的办法?...
  9. 如何发掘孩子的兴趣点
  10. 深圳银行卡收单市场明年全部开放