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. Jenkins入门教程

    Jenkins入门教程 @ 目录 Jenkins入门教程 1. 什么是Jenkins 1.1 我们为啥需要jenkins 1.2. Jenkin实现原理 2. Jenkins搭建 2.1. Jenki ...

  2. Spring Boot 核心配置文件 bootstrap & application

    Spring Boot 核心配置文件 bootstrap & application 1.SpringBoot bootstrap配置文件不生效问题 2.bootstrap/ applicat ...

  3. isEmpty isBlank 区别

    Sring test="  "; 这个 isblank 返回 true 但是 isEmpty 返回 false   所以: 一般用 isBlank 就可以了 ,是逐个字符检查 pu ...

  4. java 去掉重复的数字

    public static void main(String[] args) { String s="1,2,2,2,2,2,3,3,3"; String[] array = s. ...

  5. 制作MySQL的Windows服务+创建用户及授权

         在上一篇随笔中详述了MySQL的Windows 64位版本的安装,以及初始化操作.启动服务端.客户端连接.一些基本的文件操作等.然而在进行这些操作的时候,需要我们去输入一长串的路径和命令才能 ...

  6. 开发环境管理利器Vagrant

    引言 不知道你是否经历过,开发环境与生产环境不一致.Windows开发和Linux上的包效果不一样.在我这运行时好的啊 等等等问题,那有没有解决方法呢? 答案就是Vagrant.Docker 1.简介 ...

  7. 微信支付V3 SDK Payment Spring Boot 1.0.6 发布,实现留守红包,助力抗疫

    春节将至,为防控疫情,多地政府提倡员工.外来务工者留守本地过年,并鼓励企业向员工发放"留守红包".为此,微信支付推出"春节留守红包"能力,希望可以协助有发放需求 ...

  8. HDU 6900 Residual Polynomial【分治 NTT】

    HDU 6900 Residual Polynomial  题意: 给出一个多项式\(f_1(x) = \sum_{i=0}^na_ix^i\) 对于任意\(i>=2\),满足\(f_i(x) ...

  9. BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆

    BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...

  10. Codeforces Round #570 (Div. 3) B. Equalize Prices、C. Computer Game、D. Candy Box (easy version)、E. Subsequences (easy version)

    B题题意: 给你n个物品的价格,你需要找出来一个值b,使得每一个物品与这个b的差值的绝对值小于k.找到最大的b输出,如果找不到,那就输出-1 题解: 很简单嘛,找到上下限直接二分.下限就是所有物品中最 ...