当前位置: 首页 > news >正文

什么是ForkJoin

1、什么是ForkJoin?

从JDK1.7开始,Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任 务,最终汇总每个小任务的结果得到这个大任务的结果。

简单来说:就是借助于ForkJoin线程池,我们可以将一个大的任务分割成多个小的任务并行执行并汇总执行结果。在这里看很像我们之前学过的归并排序的逻辑一样。


2、ForkJoin如何解决问题?


**ForkJoin主要分为两步:

第一:任务切分
第二:结果合并

在这里插入图片描述

简单来说,ForkJoin也是一个线程池,而在ForkJoin线程池里面的每个线程都有自己的一个工作序列,当自己队列中的任务都完成以后,会从其他线程的工作队伍中偷一个任务执行,这样就可以充分利用资源。(在这里需要和ThreadPoolExecutor自定义线程池不同,ThreadPoolExecutor中的所有线程都有共用一个工作序列)

**

3、ForkJoin核心特性:工作窃取

**

工作窃取成立的前提条件:所用队列的存储模型为双端队列。

工作窃取:ForkJoinPool的各个工作线程都会维护一个各自的任务队列,减少线程之间对于任务的竞争;

每个线程都会先保证将自己队列中的任务执行完,当自己的任务执行完之后,会去看其他线程的任务队列中是否有未处理完的任务,如果有则会帮助其他线程执行;

为了减少在帮助其他线程执行任务时发生竞争,会使用双端队列来存放任务,被窃取的任务只会从队列的头部获取任务,而窃取任务的线程每次都是从队列的尾部获取任务。
在这里插入图片描述

优点
充分利用线程进行并行计算,并减少了线程间的竞争。

缺点
需要给每个线程都要开辟一个空间,是在某些情况下还是存在竞争,比如双端队列里只有一个任务时。并且消耗了更多的系统资源,比如创建多个线程和多个双端队列。

**

4、代码实现:

**
在这里插入图片描述
在这里插入图片描述

package com.day20221008;

import java.util.concurrent.RecursiveTask;

public class ForkJoinWork extends RecursiveTask<Long> {
    private Long start;
    private Long end;
    private final static Long critical = 1000L;

    public ForkJoinWork(Long start,Long end){
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        Long length = end - start;
        if(length <= critical){
            Long sum = 0l;
            for (Long i =0l;i<=end;i++){
                sum += i;
            }
            return sum;
        }else {
            //第一步拆分任务
            Long middle = (start + end)/2;
            ForkJoinWork right = new ForkJoinWork(start, middle);
            right.fork();
            ForkJoinWork left = new ForkJoinWork(middle + 1, end);
            left.fork();

            //合并
            return right.join() + left.join();
        }

    }
}

package com.day20221008;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;

public class ForkJoinWorkImpl {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();
        //初始化ForkJoinPool池
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        //创建执行的任务
        ForkJoinWork task = new ForkJoinWork(0L, 20000000L);
        //开始计算
        ForkJoinTask<Long> result = forkJoinPool.submit(task);
        Long sum = result.get();
        long end = System.currentTimeMillis();
        System.out.println("result = "+sum+",总共花费"+(end - start));
    }
}

但是好像stream流的合并计算效率也不错!
在这里插入图片描述

相关文章:

  • OpenCV-漫水填充cv::floodFill
  • 【精品】SpringSecurity在前后端分离项目中的应用
  • MySQL知识点总结_1
  • 深入理解Python生成器
  • SpringBoot+Vue项目校园商铺系统
  • “不学数学就去当厨子”,兰大校友入选全球竞赛最强10人,决赛最后几小时才想起做题...
  • Python基础_判断语句(if、elif、else)、if 嵌套、逻辑运算符(and、or、not )、随机数的处理
  • 【C语言】小游戏系列——扫雷(内含详细过程)
  • C++系列文章 —— 类和对象篇(上)(从入门到精通合集)
  • 7.5 文件系统
  • java计算机毕业设计伊伊物流公司的管理系统源码+数据库+系统+lw文档+部署
  • PCB设计笔记
  • 图卷积神经网络(GCN)
  • 【数据结构】八大排序
  • D*(Dynamic A*)路径规划算法
  • AngularJS指令开发(1)——参数详解
  • CentOS从零开始部署Nodejs项目
  • CSS3 变换
  • CSS实用技巧
  • ECS应用管理最佳实践
  • Java编程基础24——递归练习
  • java概述
  • MySQL的数据类型
  • Selenium实战教程系列(二)---元素定位
  • sessionStorage和localStorage
  • Vue UI框架库开发介绍
  • webgl (原生)基础入门指南【一】
  • 初探 Vue 生命周期和钩子函数
  • 对超线程几个不同角度的解释
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 详解NodeJs流之一
  • 栈实现走出迷宫(C++)
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​520就是要宠粉,你的心头书我买单
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • (2)STL算法之元素计数
  • (AngularJS)Angular 控制器之间通信初探
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (转)Linq学习笔记
  • (转)setTimeout 和 setInterval 的区别
  • (转)一些感悟
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .Net 垃圾回收机制原理(二)
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • [ 渗透工具篇 ] 一篇文章让你掌握神奇的shuize -- 信息收集自动化工具
  • [20150707]外部表与rowid.txt
  • [AR]Vumark(下一代条形码)