ForkJoinPool----FJP
先看task.fork方法,含义是将当前任务,放到当前线程的工作队列中。但是第一次执行这个方法是在主线程中,主线程是不可能被FJP管理的。那么就进入ForkJoinPool.common.externalPush,在common这个default的线程池里执行这个任务,
externalPush的意思,是把外面的任务,放到当前线程池中执行。刚进入externalPush,会检查随机数不是0,workQueues不是空,这些条件第一次肯定是不满足的,那么进入externalSubmit,先初始化随机数,

ctl是一个volatile long类型的控制变量,从高到低,前16位是(当前活跃线程数-最小并发数),往后16位是(总线程数-最小并发数),再往后16位是栈顶(Treiber stack)等待线程的标志,最后16位是栈顶等待线程在线程池数组中的位置。
runState是一个volatile int类型的控制变量,来标志当前线程池运行状态,有锁住,信号,已启动,停止,终止,关闭几种状态。(当然也可以不从fork方法进来,而是pool.invoke,意味着已经有一个FJP了,直接执行任务)

FJP的逻辑很清晰:externalPush是统一入口(没有FJP,用common,有的话直接进),没初始化的进入externalSubmit,externalSubmit逻辑很清晰:初始化workQueues,初始化当前线程对应的workQueue,hash冲突了重新生成随机数rehash。都
完成之后,提交到自己的workQueue中,然后signalWork。

signalWork:方法的含义是现在新添加了一个task,需要去看下有没有满负荷(判断的标准是活跃线程是不是已经达到了并发数)。有空闲线程,那么唤起(去第三个和第四个16位找空闲线程栈顶信息,unpark方法),如果没有空闲线程但是总线程数不足(c & ADD_WORKER是判断第二个16位是正数还是负数,负数说明总线程数不足)
那么addWorker。

唤起的线程或新增的线程,会在run方法里进行无限循环,现在自己的任务队列里面找任务,找不到去别的线程的任务队列里找(steal),steal和自己从自己队列找是不同方向,所以能减少并发。直到所有的task都被取走,当前线程
挂起休眠。

ForkJoinTask.join,其实fork把任务放进任务队列之后,任务就可以被执行了,但是如果想获取任务执行的结果,需要让task.join,

ForkJoinPool 源码的更多相关文章

  1. ForkJoinPool源码简单解析

    ForkJoin框架之ForkJoinTask  java  阅读约 62 分钟 前言 在前面的文章"CompletableFuture和响应式编程"中提到了ForkJoinTas ...

  2. ForkJoinPool 源码分析

    ForkJoinPool ForkJoinPool 是一个运行 ForkJoinTask 任务.支持工作窃取和并行计算的线程池 核心参数+创建实例 // 工作者线程驻留任务队列索引位 static f ...

  3. 【JUC源码解析】ForkJoinPool

    简介 ForkJoin 框架,另一种风格的线程池(相比于ThreadPoolExecutor),采用分治算法,工作密取策略,极大地提高了并行性.对于那种大任务分割小任务的场景(分治)尤其有用. 框架图 ...

  4. Java源码之 java.util.concurrent 学习笔记01

    准备花点时间看看 java.util.concurrent这个包的源代码,来提高自己对Java的认识,努力~~~ 参阅了@梧留柒的博客!边看源码,边通过前辈的博客学习! 包下的代码结构分类: 1.ja ...

  5. 大文件拆分问题的java实践(附源码)

    引子 大文件拆分问题涉及到io处理.并发编程.生产者/消费者模式的理解,是一个很好的综合应用场景,为此,花点时间做一些实践,对相关的知识做一次梳理和集成,总结一些共性的处理方案和思路,以供后续工作中借 ...

  6. 线程池ThreadPoolExecutor源码解读研究(JDK1.8)

    一.什么是线程池 为什么要使用线程池?在多线程并发开发中,线程的数量较多,且每个线程执行一定的时间后就结束了,下一个线程任务到来还需要重新创建线程,这样线程数量特别庞大的时候,频繁的创建线程和销毁线程 ...

  7. 从源码看JDK提供的线程池(ThreadPoolExecutor)

    一丶什么是线程池 (1)博主在听到线程池三个字的时候第一个想法就是数据库连接池,回忆一下,我们在学JavaWeb的时候怎么理解数据库连接池的,数据库创建连接和关闭连接是一个比较耗费资源的事情,对于那些 ...

  8. Netty5服务端源码解析

    Netty5源码解析 今天让我来总结下netty5的服务端代码. 服务端(ServerBootstrap) 示例代码如下: import io.netty.bootstrap.ServerBootst ...

  9. 【JUC源码解析】CompletableFuture

    简介 先说Future, 它用来描述一个异步计算的结果.isDone方法可以用来检查计算是否完成,get方法可以用来获取结果,直到完成前一直阻塞当前线程,cancel方法可以取消任务.而对于结果的获取 ...

随机推荐

  1. python多环境下虚拟环境的搭建和使用

    由于开发环境要求,或者实际需要.经常会出现python2.7和python3.x共存下的开发环境问题.虚拟环境的搭建可以很好的隔离Projects的开发环境. 1.首先解决python2.7和pyth ...

  2. [原][杂谈]如果人类的末日:"天网"出现

    本文由南水之源在2019年3月21日发布,转载需声明原作者 本文仅为一次基于科技发展与科幻小说的幻想,如果天网真的出现,请不要参考这篇逻辑破败的推论. 参考: 天网(Skynet),是电影<终结 ...

  3. Go语言学习之14 商品秒杀架构设计与开发

    本节主要内容 1. 秒杀抢购背景2. 秒杀抢购架构设计&模块划分3. 秒杀抢购接入层实现 1. 秒杀抢购背景 (1)架构分析 电商网站架构 秒杀抢购1.0 (2)上述网站架构问题 和已有电商逻 ...

  4. 如何利用redis来进行分布式集群系统的限流设计

    在很多高并发请求的情况下,我们经常需要对系统进行限流,而且需要对应用集群进行全局的限流,那么我们如何类实现呢. 我们可以利用redis的缓存来进行实现,并且结合mysql数据库一起,先来看一个流程图. ...

  5. Expression基础体验

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; usin ...

  6. C语言函数声明什么时候可以省略,什么时候不能省?

    在学习C语言函数的时候,老师总会告诉我们函数要写声明,然后再定义.这是个稳健的做法.等我自己学习了其他高级语言以后,回头再来写C,突然就觉得函数要写声明有点麻烦.无意间发现有一次函数没写声明居然编译( ...

  7. GIS开发 图形常见算法

    摘录:OSGeo中国中心 http://www.osgeo.cn/post/ae457 计算机的出现使得很多原本十分繁琐的工作得以大幅度简化,但是也有一些在人们直观看来很容易的问题却需要拿出一套并不简 ...

  8. android使用smack实现简单登录功能

    android端采用xmpp协议实现即时通讯,在最开始的登录功能就遇到了不少障碍.首先在官网(https://www.igniterealtime.org/projects/openfire/)下载o ...

  9. javascript高级程序设计第3版——第10章 DOM

    第十章,DOM DOM是语言中立的API,用于访问和操作HTML 和XML 文档.DOM1 级将HTML 和XML 文档形象地看作一个层次化的节点树,可以使用JavaScript 来操作这个节点树,进 ...

  10. css三种基本选着器

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...