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

线程池主要控制的状态是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. request和response中文乱码问题后台处理办法

    request接收参数的中文乱码的处理: GET: 方法一:使用String的构造方法: new String(request.getParameter("传过来的name").g ...

  2. Java爬虫——人人网模拟登录

    人人网登录地址:http://www.renren.com/ 此处登录没有考虑验证码验证码. 首先对登录方法进行分析 有两种方法. 一)在Elements中分析源码 发现登录点击后的事件是http:/ ...

  3. 剑指Offer_5_替换空格

    题目描述 请实现一个函数,将一个字符串中的空格替换成"%20". 例如,当字符串为We Are Happy.则经过替换之后的字符串为 We%20Are%20Happy. 在网络编程 ...

  4. BNUOJ34977夜空中最亮的星(数学,向量的应用)

    夜空中最亮的星 Time Limit: 2000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name ...

  5. 局域网使用的IP地址范围

    局域网可用的IP地址范围为: A类地址:10.0.0.0 - 10.255.255.255  B类地址:172.16.0.0 - 172.31.255.255 C类地址:192.168.0.0 -19 ...

  6. EventBus在Android中的简单使用

    EventBus是一个方便与Android中各组件通信的开源框架,开源地址;https://github.com/greenrobot/EventBus.EventBus功能非常强大 ,今天在做一个功 ...

  7. Android TCP/IP 扫盲教程

    TCP/IP 是因特网的通信协议. 通信协议是对计算机必须遵守的规则的描写叙述.仅仅有遵守这些规则.计算机之间才干进行通信. 浏览器和server都在使用 TCP/IP 因特网浏览器和因特网serve ...

  8. Struts2学习笔记整理(三)

    Struts2的输入校验 之前对请求参数的输入校验一般分为两部分:1.客户端校验,也就是我们写js代码去对客户的误操作进行过滤  2.服务端校验, 这是整个应用组织非法数据的最后防线. Struts2 ...

  9. 自学Zabbix2.1-安装需求

    zabbix的安装需求通常就是硬件配置.软件需求,或者说我安装zabbix需要什么软件,服务器需要什么样的配置,监控100台服务器需要怎样的一台服务器,或者我有一台8核16G的服务器,我能监控多少台服 ...

  10. Linux服务器配置(一)

    Linux服务器配置(一) jdk,tomcat,nginx记录 最近公司买了三台服务器System x3650 M5用来跑公司的项目.现,记录一下真机部署与后期维护历程~ 因为系统是服务器买来就装好 ...