ForkJoinPool 分支/合并框架
ForkJoinPool 分支/合并框架
一、Fork/Join框架简介
Fork/Join 框架就是在必要的情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行join 汇总。
如下图所示:
二、Fork/Join 框架与线程池的区别
采用“工作窃取”模式(work-stealing):
当执行新的任务时它可以将其拆分分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。
相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的处理方式上.在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态。而在fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而无法继续运行。那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行.这种方式减少了线程的等待时间,提高了性能。
三、示例代码
对0L,到50000000000L进行求和
package me.concurrent.fjp; import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream; import org.junit.Test; public class TestForkJoinPool { public static void main(String[] args) {
Instant start = Instant.now(); ForkJoinPool pool = new ForkJoinPool(); ForkJoinTask<Long> task = new ForkJoinSumCalculate(0L, 50000000000L); Long sum = pool.invoke(task); System.out.println(sum); Instant end = Instant.now(); System.out.println("耗费时间为:" + Duration.between(start, end).toMillis());// 166-1996-10590
} @Test
public void test1() {
Instant start = Instant.now(); long sum = 0L; for (long i = 0L; i <= 50000000000L; i++) {
sum += i;
} System.out.println(sum); Instant end = Instant.now(); System.out.println("耗费时间为:" + Duration.between(start, end).toMillis());// 35-3142-15704
} // java8 新特性
@Test
public void test2() {
Instant start = Instant.now(); Long sum = LongStream.rangeClosed(0L, 50000000000L).parallel().reduce(0L, Long::sum); System.out.println(sum); Instant end = Instant.now(); System.out.println("耗费时间为:" + Duration.between(start, end).toMillis());// 1536-8118
} } class ForkJoinSumCalculate extends RecursiveTask<Long> { private static final long serialVersionUID = -259195479995561737L; private long start;
private long end; private static final long THURSHOLD = 10000L; // 临界值 public ForkJoinSumCalculate(long start, long end) {
this.start = start;
this.end = end;
} @Override
protected Long compute() {
long length = end - start; if (length <= THURSHOLD) {
long sum = 0L; for (long i = start; i <= end; i++) {
sum += i;
} return sum;
} else {
long middle = (start + end) / 2; ForkJoinSumCalculate left = new ForkJoinSumCalculate(start, middle);
left.fork(); // 进行拆分,同时压入线程队列 ForkJoinSumCalculate right = new ForkJoinSumCalculate(middle + 1, end);
right.fork(); // return left.join() + right.join();
}
} }
main方法运行结果
-4378596987249509888
耗费时间为:36950(毫秒)
CPU利用率几乎100%!!!
如果,您对我的这篇博文有什么疑问,欢迎评论区留言,大家互相讨论学习。
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博文感兴趣,可以关注我的后续博客,我是【AlbertRui】。转载请注明出处和链接地址,欢迎转载,谢谢!
ForkJoinPool 分支/合并框架的更多相关文章
- 11.ForkJoinPool 分支/合并框架 (工作窃取)
/*ForkJoinPool 分支/合并框架 (工作窃取)*/ Fork/Join 框架:就是在必要的情况下,将一个大任务,进行拆分(fork) 成若干个小任务(拆到给出的临界值为止),再将一个个的小 ...
- java多线程 -- ForkJoinPool 分支/ 合并框架 工作窃取
Fork/Join 框架:就是在必要的情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行 join 汇总. Fork/Join 框架与线程池的 ...
- ForkJoinPool分支合并框架-工作窃取
Fork/Join 框架 Fork/Join 框架:就是在必要的情况下,将一个大任务,进行拆分(fork)成 若干个小任务(拆到不可再拆时), 再将一个个的小任务运算的结果进行 join 汇总 For ...
- ForkJoinPool分支/合并框架工程使用的工作窃取
ForkJoinPool分支/合并框架 在必要的情况下,讲一个大任务,进行拆分(fork)成若干个小任务(拆到不可拆为止),再将一个个小的任务运算的结果进行join汇总. 工作窃取的背景 分支/合并框 ...
- JUC-分支合并框架
一.原理 Fork:把一个复杂任务进行分拆,大事化小 Join:把分拆任务的结果进行合并 ForkJoinPool 分支合并池 类比=> 线程池 ForkJoinTask ForkJo ...
- JUC---08ForkJion(分支合并)
一.什么是ForkJion Fork/Join框架是Java7提供的并行执行任务框架,思想是将大任务分解成小任务,然后小任务又可以继续分解,然后每个小任务分别计算出结果再合并起来,最后将汇总的结果作为 ...
- 分支合并git checkout adview git merge adview3
分支合并 git checkout adview git merge adview3
- (转)SVN分支/合并原理及最佳实践
先说说什么是branch.按照Subversion的说法,一个branch是某个development line(通常是主线也即trunk)的一个拷贝,见下图: branch存在的意义在于,在不干扰t ...
- ECLIPSE下SVN的创建分支/合并/切换使用
最近接项目要求,要在svn主干上创建分支,用分支来进行程序的bug修改,而主干上进行新功能的开发.分支上的bug修改完,发布后,可以合并到主干上.项目程序可以在主干和分支之间进行切换,来实现主干和分支 ...
随机推荐
- 数组(ArrayPool数组池、Span<T>结构)
前言 如果需要使用相同的类型的多个对象,就可以使用集合和数组,这一节主要讲解数组,其中会重点涉及到Span<T>结构和ArrayPool数组池.我们也会先涉及到简单的数组.多维数组.锯齿数 ...
- SQL数据同步到ElasticSearch(三)- 使用Logstash+LastModifyTime同步数据
在系列开篇,我提到了四种将SQL SERVER数据同步到ES中的方案,本文将采用最简单的一种方案,即使用LastModifyTime来追踪DB中在最近一段时间发生了变更的数据. 安装Java 安装部分 ...
- 华三F100 系列防火墙 - 浮动路由联动NQA 实现双线路自动切换
公司 有两条公网线路,一条移动作为日常主用线路,一条联通作为备用线路. 为了实现主备线路自动切换,配置了浮动路由 但浮动路由只能在 主用接口为down状态时才能浮出接管默认路由.如果故障为非物理链路故 ...
- jsp对数据库的使用
JDBC由Sun公司制定,全称JavaDataBase Connectivity,是一种可以执行SQL语句并可返回结果的javaAPI,支持多种关系型数据库,封装在Java.sql.* 它的具体位置在 ...
- Java 第四章
switch选择结构 语法:switch(表达式){ case 常量 1: //代码块1: break: case 常量 2: //代码块2: break: ...... default ...
- 简易数据分析 08 | Web Scraper 翻页——点击「更多按钮」翻页
这是简易数据分析系列的第 8 篇文章. 我们在Web Scraper 翻页--控制链接批量抓取数据一文中,介绍了控制网页链接批量抓取数据的办法. 但是你在预览一些网站时,会发现随着网页的下拉,你需要点 ...
- C# Winfrom 自定义控件——带图片的TextBox
效果: 描述: 本来是想用GDI在左边画图片上去的,文本是居中对齐,如果文本是左对齐,文本会把图片遮住控件长这样: 但这样做,输入框在获取焦点时候,会把图片挡住就像这样: 输入完成之后图片就会显示完整 ...
- web渗透---第二天
协议常识 HTTP协议 百度百科的解释:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议. 所有的WWW文件都必须遵守这个标准. ...
- 0x02 递推与递归
[例题]CH0301 递归实现指数型枚举 #include <iostream> #include <cstdio> #include <algorithm> #i ...
- Redis——基础使用
Redis总体介绍: Redis特性 Redis(REmote DIctionary Server),是一个开源的内存数据库 持久化:RDB.AOF 主备复制 丰富的数据结构 Lua脚本.事务 Red ...