上面这段代码一直在用,面试的时候也经常被问到,却从未深究过,不知道线程池到底是怎么回事,今天看看源代码,一探其究竟

线程池主要控制的状态是ctl,它是一个原子的整数,其包含两个概念字段:

  • workerCount:有效的线程数量
  • runState:线程池的状态

为了在一个整型值里面包含这两个字段,我们限制workerCount最多2的29次方减1

runState的值有这样几种:

  • RUNNING:  接受新的任务,并处理队列中的任务
  • SHUTDOWN:不接受新的任务,继续处理队列中的任务
  • STOP:           不接受新的任务,也不处理队列中的任务,并且中断正在处理的任务
  • TIDYING:      所有任务都结束了,workerCount是0,通过调用terminated()方法转换状态
  • TERMINATED:terminated()方法已经完成

状态之间的转换时这样的:

RUNNING -> SHUTDOWN

  调用shutdown()方法,或者隐式的调用finalize()方法

(RUNNING or SHUTDOWN) -> STOP

  调用shoutdownNow()方法

SHUTDOWN -> TIDYING

  当队列和池都是空的时候

STOP -> TIDYING

  当池是空的时候

TIDYING -> TERMINATED

  当terminated()方法调用完成时

Integer.SIZE=31

Integer.SIZE - 3 = 29

所以,COUNT_BITS = 29

高3位存储runState

接下来看最复杂的那个构造方法

参数详解

  • corePoolSize:保持在池中的线程数(PS:即使它们处于空闲状态)
  • maximumPoolSize:池中允许的最大线程数
  • keepAliveTime:当线程数超过核心线程数的时候,超出的线程的最大生存时间
  • unit:keepAliveTime的单位
  • workQueue:维护待处理的任务的队列
  • threadFactory:创建线程的工厂

1、如果正在运行的线程数少于核心线程数,则新建一个线程去运行这个任务

2、如果工作队列没有满,则放到工作队列中

3、如果工作队列已满(PS:workQueue.offer(command)返回false),则再新建线程

4、若线程数已经达到最大线程数则reject(command)

在前面execute方法中,有3处调用了addWork()方法

第一处,如果当前有效线程数少于核心线程数,则调用之,此时线程数的边界是核心线程数

第二处,如果当前有效线程数超过核心线程数,并且将新任务放到队列中,此时有效线程数是0,则创建一个新线程

第三处,如果当前有效线程数超过核心线程数,并且队列已经放满了,并且有效线程数小于最大线程数,此时调用以创建新线程,

当前的有效线程都在works里面,而works里面放的是Worker对象,接下来看Worker

前一步中,线程的start()方法,线程运行的时候执行run()方法,而Worker继承Runnable并重新run()方法,run()方法又调用外部的runWorker()方法,所以,在线程池中新创建的线程运行时调用的是runWorker()方法

runWorker()方法循环的从队列中取出任务并执行它。也就是说,池中所有的线程都是在创建的时候如果传进来新任务,则先执行新任务,然后循环从队列中取出任务并执行

接下来,看Executors中常见的几种线程池的区别

可以看到

newSingleThreadExecutor:核心线程数和最大线程数都是1,队列是LinkedBlockingQueue

newFixedThreadPool:核心线程数和最大线程数相等,超过核心线程数的空闲线程生存时间是0,队列是LinkedBlockingQueue

newCachedThreadPool:核心线程数是0,最大线程数是Integer.MAX_VALUE,空闲线程生存时间是1min,队列是SynchronousQueue

JDK1.8中的线程池的更多相关文章

  1. 【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

    碎碎念 关于JDK源码相关的文章这已经是第四篇了,原创不易,粉丝从几十人到昨天的666人,真的很感谢之前帮我转发文章的一些朋友们. 从16年开始写技术文章,到现在博客园已经发表了222篇文章,大多数都 ...

  2. android中的线程池学习笔记

    阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...

  3. Java5中的线程池实例讲解

    Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活.本文通过一个网络服务器模型,来实践Java5的多线程 ...

  4. Spring中的线程池和定时任务功能

    1.功能介绍 Spring框架提供了线程池和定时任务执行的抽象接口:TaskExecutor和TaskScheduler来支持异步执行任务和定时执行任务功能.同时使用框架自己定义的抽象接口来屏蔽掉底层 ...

  5. jdk1.7中的常量池

    在探究jdk1.7中的常量池,我们可以先看看以下的这段代码 public static void main(String[] args) throws Throwable { List<Stri ...

  6. 探究ElasticSearch中的线程池实现

    探究ElasticSearch中的线程池实现 ElasticSearch里面各种操作都是基于线程池+回调实现的,所以这篇文章记录一下java.util.concurrent涉及线程池实现和Elasti ...

  7. 使用concurrent.futures模块中的线程池与进程池

    使用concurrent.futures模块中的线程池与进程池 线程池与进程池 以线程池举例,系统使用多线程方式运行时,会产生大量的线程创建与销毁,创建与销毁必定会带来一定的消耗,甚至导致系统资源的崩 ...

  8. C#中的线程池使用(一)

    1  线程池的概念 许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生.其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态.为了简化 ...

  9. mina2中的线程池

    一.Mina中的线程池模型 前面介绍了Mina总体的层次结构,那么在Mina里面是怎么使用Java NIO和进行线程调度的呢?这是提高IO处理性能的关键所在.Mina的线程调度原理主要如下图所示: A ...

随机推荐

  1. Python Django CMDB项目实战之-3创建form表单,并在前端页面上展示

    基于之前的项目代码 Python Django CMDB项目实战之-1如何开启一个Django-并设置base页.index页.文章页面 Python Django CMDB项目实战之-2创建APP. ...

  2. Power Designer如何批量改动数据类型

    最近做项目的时候须要将OOM转换为PDM.在OOM中转换为PDM时,全部string的类型的属性都默认变为varchar(254),这可不是我们须要的类型,那么.如此多的类.如此多的属性.难道一个一个 ...

  3. opencv批处理提取图像的特征

    ____________________________________________________________________________________________________ ...

  4. JIRA 敏捷开发平台部署记录

    1.1 jira说明 JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪.客户服务.需求收集.流程审批.任务跟踪.项目跟踪和敏捷管理等工作领域. JIRA中配置灵活.功能全 ...

  5. QQ 相册后台存储架构重构与跨 IDC 容灾实践

    欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~ 作者简介:xianmau,2015 年加入腾讯 TEG 架构平台部,一直负责 QQ 相册平台的维护和建设,主导相册上传架构重构和容灾优化等工作. ...

  6. mysql还原数据库时,提示ERROR 1046 (3D000) No database selected 的解决方法

    使用mysql数据库的朋友, 经常会使用mysqldump备案数据库, 然后到新服务器还原, 这个过程中, 有朋友会遇到ERROR 1046 (3D000)  No database selected ...

  7. git 设置和取消代理

    # 设置ss git config --global http.proxy 'socks5://127.0.0.1:1080' git config --global https.proxy 'soc ...

  8. 【java】io流之字符输出流:java.io.Writer类及子类的子类java.io.FileWriter

    package 文件操作; import java.io.File; import java.io.FileWriter; import java.io.IOException; import jav ...

  9. list.add(),向List集合插入对象报空指针异常

    开始的时候我没有判断添加的随想是否为空,直接add;后来加了一个判断,判断了对象不等于空,但是运行程序还是报空指针,这时我发现应该是List出问题了: 查了下资料,发现我初始化List方法不对,如果只 ...

  10. UIImage类方法总结及UIImage生成方法对比

    http://mp.weixin.qq.com/s/A900w0Y5pGjuaB4j9Os9ww1.UIImage 生成方法的对比 Apple官方的文档为生成一个UIImage对象提供了两种方法: 1 ...