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. vue 打开新窗口

    const {href} = this.$router.resolve({ name: 'foo', query: { bar } }) window.open(href, '_blank')

  2. C# 封装SDK 获取摄像头的水平角度和垂直角度

    最近需要做一个C#版本的控制终端,控制摄像头,获取摄像头的水平角度和垂直角度 获取当前摄像头的角度,需要调用一个名为NET_DVR_GetDVRConfig的bool类型的函数 在C++中,函数定义: ...

  3. IBase<T>

    public interface IBase<T>//基类 { IEnumerable<T> SelectAll();//查询所有 T FindById(int ID);//根 ...

  4. 【VS工具】vs2017中的一些小功能

    一.json转为类 1.打开一个json文件,复制 2.打开一个.cs文件,将json粘贴为类 3.got it 二.C#交互窗口 1.视图->其他窗口->C#交互窗口  2.打开了一个窗 ...

  5. setTimeout异步

    同步任务和异步任务 同步和异步操作的区别就是是否阻碍后续代码的执行. 同步任务是那些没有被引擎挂起.在主线程上排队执行的任务.只有前一个任务执行完毕,才能执行后一个任务. 异步任务是那些被引擎放在一边 ...

  6. HDU 1024 Max Sum Plus Plus(DP的简单优化)

    Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To b ...

  7. 1GB pages can only be allocated at boot time using hugepages= and not freed afterwards

    2018-6-27 9:12:38 https://stackoverflow.com/questions/26385554/error-setting-nr-hugepages-via-sysfs ...

  8. 记一次linux上的ftp搭建过程

    最近公司测试环境需要搭建ftp,正好自己稍微有点空且这方面确实不会,就自告奋勇说让我先试试,玩炸了你们再帮忙重装系统重新搭吧(手动滑稽),虽然最终是完成了,但是中间磕磕碰碰遇到一些小问题,到处查百度, ...

  9. VSCode中使用vue项目ESlint验证配置

    如果在一个大型项目中会有多个人一起去开发,为了使每个人写的代码格式都保持一致,就需要借助软件去帮我们保存文件的时候,自己格式化代码 解决办法:vscode软件下载一个ESLint,在到设置里面找到se ...

  10. useragent大全

    分享几个常见的User-Agent,复制粘贴过来的,谢谢原创. window.navigator.userAgent 1) Chrome Win7: Mozilla/5.0 (Windows NT 6 ...