ForkJoin


什么是 ForkJoin

ForkJoin 是一个把大任务拆分为多个小任务来分别计算的并行计算框架

ForkJoin 特点:工作窃取

这里面维护的都是双端队列,因此但其中一个线程完成自己的计算任务之后,可以从其他线程任务队列另一端“窃取”任务进行计算,从而提高计算效率!

ForkJoin 执行流程

伪代码:

if(任务数小){
直接计算
}else{
将问题划分为独立的部分
分叉新的子任务来解决每个部分
加入所有子任务进行计算
将子结果进行合并
}

ForkJoinPool: 核心

ForkJoinTask:

RecursiveTask:递归任务


package juc.forkJoin;

import java.util.concurrent.RecursiveTask;

/*
求和计算的任务!
普通求和 ForkJoin Stream并行流
如何使用ForkJoin
1、ForkJoinPool 通过它来执行
2、计算任务 ForkJoinPool.execute(ForkJoinTask task)
3、ForkJoinTask 是一个接口,execute方法传入参数应为 ForkJoinTask 的子类 如 RecursiveTask */
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;//开始值
private Long end;//结束值
private Long temp=10000L;//阈值,用于区分是否用ForkJoin来进行划分 public ForkJoinDemo(Long start,Long end){
this.start=start;
this.end=end;
} @Override
protected Long compute() {
if ((end-start)<=temp){//小于等于阈值,则直接进行计算
Long sum=0L;
for (Long i = start; i <= end; i++) {
sum+=i;
}
return sum;
}else {//大于阈值使用ForkJoin进行划分
//任务拆分点
Long middle=(start+end)/2;
ForkJoinDemo task1 = new ForkJoinDemo(start, middle);
task1.fork();
ForkJoinDemo task2 = new ForkJoinDemo(middle + 1, end);
task2.fork(); return task1.join()+task2.join(); }
}
}

测试类:

package juc.forkJoin;

import java.util.OptionalLong;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream; public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//计算结果:500000000500000000
test1();
test2();
test3();
test4();
}
//普通方法
public static void test1(){
Long startTime=System.currentTimeMillis();
Long sum=0L;
for (Long i = 1L; i <= 10_0000_0000L; i++) {
sum+=i;
}
Long endTime=System.currentTimeMillis();
System.out.println("计算结果:"+sum);
System.out.println("普通方法耗时:"+(endTime-startTime));
}
//ForkJoin方法
public static void test2() throws ExecutionException, InterruptedException {
Long startTime=System.currentTimeMillis(); ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinDemo(1L, 10_0000_0000L);
ForkJoinTask<Long> submit = pool.submit(task);
Long result = submit.get(); Long endTime=System.currentTimeMillis();
System.out.println("计算结果:"+result);
System.out.println("ForkJoin方法耗时:"+(endTime-startTime));
}
//Stream并行流方法
public static void test3(){
Long startTime=System.currentTimeMillis(); //Stream并行流 parallel()并行流 sequential()串行流
OptionalLong reduce = LongStream.rangeClosed(1L, 10_0000_0000L).parallel().reduce(Long::sum);
Long result = reduce.getAsLong(); Long endTime=System.currentTimeMillis();
System.out.println("计算结果:"+result);
System.out.println("Stream并行流方法耗时:"+(endTime-startTime));
}
//Stream串行流方法
public static void test4(){
Long startTime=System.currentTimeMillis(); OptionalLong reduce = LongStream.rangeClosed(1L, 10_0000_0000L).sequential().reduce(Long::sum);
Long result = reduce.getAsLong(); Long endTime=System.currentTimeMillis();
System.out.println("计算结果:"+result);
System.out.println("Stream串行流方法耗时:"+(endTime-startTime));
}
}

运行结果:

ForkJoin、并行流计算、串行流计算对比的更多相关文章

  1. Java8的新特性--并行流与串行流

    目录 写在前面 Fork/Join框架 Fork/Join框架与传统线程池的区别 传统的线程池 Fork/Join框架 Fork/Join框架的使用 Java8中的并行流 写在前面 我们都知道,在开发 ...

  2. 【Java8新特性】关于并行流与串行流,你必须掌握这些!!

    写在前面 提到Java8,我们不得不说的就是Lambda表达式和Stream API.而在Java8中,对于并行流和串行流同样做了大量的优化.对于并行流和串行流的知识,也是在面试过程中,经常被问到的知 ...

  3. JDK8--07:并行流与串行流

    JDK8中,提供了并行流和串行流,使用parallel()和sequential()来处理,parallel()为并行流sequential()为串行流,两者可以相互转换,以最后一个为准 LongSt ...

  4. 三、并行流与串行流 Fork/Join框架

    一.并行流概念: 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. java8中将并行进行了优化,我们可以很容易的对数据进行并行操作.Stream API可以声明性的通过pa ...

  5. Java8新特性 并行流与串行流 Fork Join

    并行流就是把一个内容分成多个数据块,并用不同的线程分 别处理每个数据块的流. Java 8 中将并行进行了优化,我们可以很容易的对数据进行并 行操作. Stream API 可以声明性地通过 para ...

  6. Java8新特性 - 并行流与串行流

    并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作.Stream API可以声明性地通过parallel()和 ...

  7. Silverlight并行下载与串行下载

    思路清晰后仅仅只需百来行代码便可轻松编写出一套完整的资源动态下载组件- SerialDownloader和ParallelDownloader,它们共用一个完成资源表,且串行下载集成了优先机制(Dow ...

  8. for循环与串行化、并行化Stream流性能对比

    第四章 并行化Stream流 关注公众号(CoderBuff)回复"stream"获取<Java8 Stream编码实战>PDF完整版. <Java8 Strea ...

  9. 串行移位锁存并行输出可级联器件74HC595

    一.背景 老同学今天突然咨询关于74HC595,自己没用过,同学说可以级联10级!10级?我艹,这么叼,级联又是 什么鬼,这勾起了我极大兴趣,二话不说,手册down下来研究,并在此做个记录. 二.正文 ...

随机推荐

  1. Java 操作 HBase 教程

    Java 操作 HBase 教程 一.简介 二.hbase-client 引入 三.连接操作 四.表操作 五.运行测试 相关博文原文地址: 博客园:美码师:HBase(2) Java 操作 HBase ...

  2. NATAPP--实现SSH内网穿透

    NATAPP--实现SSH内网穿透 1. 关于Natapp 2. 使用Natapp 3. Natapp安装和配置 4. XShell连接 相关参考博文原文地址: CSDN:KevenPotter:NA ...

  3. RIDE对应驱动下载

    https://blog.csdn.net/apollolkj/article/details/75408237

  4. MySQL特殊字符的转义处理

    出现问题以及问题分析 这条语句会把user_name不为空的所有记录查询出来 select * from user where user_name like concat('%','_','%') 分 ...

  5. 图片轮播展示效果-2D实现

    图片的轮播展示效果如果使用2D实现,需要将3D中存在的近大远小效果使用图片的缩放呈现,因此需要存储和计算图片的位置同时还要计算存储图片的缩放信息.将所有图片的位置连线看作是一个椭圆,就可以根据图片的个 ...

  6. 烧录失败导致boot无法加载的解决措施,再也不怕烧成砖了

    目录: 1.usb烧录时出现的问题截图 2.重新擦除boot发现失败的情况 3.解决措施 烧录失败导致boot无法加载的解决措施在烧录系统的时候经常会遇到烧录失败的情况,如果能通过再次执行烧录能烧上肯 ...

  7. vue-cli3移动端自适应配置 Vant组件库

    module.exports = { presets: [ '@vue/app' ], plugins: [ ['import', { libraryName: 'vant', libraryDire ...

  8. 小白的经典CNN复现(三):AlexNet

    小白的经典CNN复现(三):AlexNet 锵锵--本系列的第三弹AlexNet终于是来啦(≧∀≦),到了这里,我们的CNN的结构就基本上和现在我们经常使用或者接触的一些基本结构差不多了,并且从这一个 ...

  9. B - 规律题2

    10 123456 1:f(y)=1+2+3+4+5+6=21 2:f(y)=3 3        3 b进制,<b; 10 123 1+2+3=6;是3的倍数 1234 =(999)*1+99 ...

  10. 2019牛客暑期多校训练营(第一场)E ABBA (DP/卡特兰数)

    传送门 知识点:卡特兰数/动态规划 法一:动态规划 由题意易知字符串的任何一个前缀都满足\(cnt(A) - cnt(B) \le n , cnt(B)-cnt(A)\le m\) \(d[i][j] ...