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. 【PY从0到1】第七节 函数

    # 7 第七节 函数 # 函数对于编程语言来说是一块重量级的内容. # 他可以实现或者简化编写的代码. # 编写好特定功能的函数后,就可以重复调用函数来完成任务. # 下面我们就用函数的形式来封装前面 ...

  2. kubernetes 身份与权限认证 (ServiceAccount && RBAC)

    Kubernetes中提供了良好的多租户认证管理机制,如RBAC.ServiceAccount还有各种Policy等.   ServiceAccount Service Account为Pod中的进程 ...

  3. Centos7 安装RabbitMQ 3.6.1

    如果你看过前两章对RabbitMQ已经有了一定了解,现在已经摩拳擦掌,来吧动手吧! 用什么系统 本文使用的是Centos7,为了保证对linux不太熟悉的伙伴也能轻松上手(避免折在安装的路上),下面是 ...

  4. php 7.4 vcruntime140.dll not compatible with PHP

    安装PHP7.4以上版本时,在运行PHP时会提示如下: PHP Warning: 'vcruntime140.dll' 14.0 is not compatible with this PHP bui ...

  5. Birkhoff-von Neumann Crossbar 光交换网络的调度方案

    Birkhoff-von Neumann Crossbar 光交换网络的调度方案 ​ This is a summary aimed at looking for "high perform ...

  6. 克鲁斯卡尔算法(Kruskal算法)求最小生成树

    题目传送:https://loj.ac/p/10065 1.排序函数sort,任何一种排序算法都行,下面的示例代码中,我采用的是冒泡排序算法 2.寻源函数getRoot,寻找某一个点在并查集中的根,注 ...

  7. Educational Codeforces Round 86 (Div. 2)

    比赛链接:https://codeforces.com/contest/1342 A - Road To Zero 题意 有两个非负整数 x, y 以及两种操作: 支付 a 点代价使其中一个数加一或减 ...

  8. zjnu1725 COCI (类似二维树状数组模拟)

    Description The 3rd round of COCI is already here! In order to bet on predict the scores, we have as ...

  9. Python3.9.1中如何使用match方法?

    接触编程的朋友都听过正则表达式,在python中叫re模块,属于文字处理服务里面的一个模块.re里面有一个方法叫match,接下来的文章我来详细讲解一下match. 作为新手,我建议多使用帮助文档,也 ...

  10. linux下安装python3.7.2

    1.到python的官网去下载python3.7.2安装包,必须是Linux版本的 2.在/usr/tmp下下载python安装包 wget https://www.python.org/ftp/py ...