系列目录

线程数量的维护

线程池的大小有两个重要的参数,一个是corePoolSize(核心线程池大小),另一个是maximumPoolSize(最大线程大小)。线程池主要根据这两个参数对线程池中线程的数量进行维护。

需要注意的是,线程池创建之初是没有任何可用线程的。只有在有任务到达后,才开始创建线程,并复用线程。

注:此图不是状态图,不是说添加一个线程就直接到达corePoolSize状态,而是要表示,一直添加线程直到达到corePoolSize。

注释里也写的很清楚了:

(1)如果线程数未达核心数,则每接收一个任务就创建一个工作线程(这里把Worker视为工作线程)来处理。

(2)如果线程数已达到核心数,那就把任务先放入队列。等到有工作线程完成任务了,会自行从队列中取任务做。

(3)如果任务无法放入队列,如队列是有界队列,且已满。那么就会继续创建工作线程来处理这个任务。注意,这里的新线程已经不是核心线程了。

(4)如果线程数量已经达到maxPoolSize,这时候就是线程不能再创建了,任务也放不进队列了,就得启动reject策略。默认策略是AbortPolicy,也就是直接报异常。

public void execute(Runnable command) {
//非空检查
if (command == null)
throw new NullPointerException(); //获取线程池控制信息
int c = ctl.get();
//通过workerCountOf方法获取控制信息内的工作线程数信息
//如果小于核心线程数,执行addWorker方法 0 => corePoolSize
if (workerCountOf(c) < corePoolSize) {
//这个操作添加的是核心工作线程,且有初始任务
if (addWorker(command, true))
return; //如果操作成功直接返回
//由于addWorker操作对工作线程数,可能有所更改,故重新获取控制信息
c = ctl.get();
} //添加核心线程失效后
//如果线程池处于运行状态,且任务成功加入阻塞队列 corePoolSize => corePoolSize
if (isRunning(c) && workQueue.offer(command)) {
//再次检查线程池状态
int recheck = ctl.get();
//如果线程池处于非运行状态,则把刚刚加入队列的任务移除
if (! isRunning(recheck) && remove(command))
//执行拒绝策略
reject(command);
//当前没有工作者线程,则添加非核心线程
else if (workerCountOf(recheck) == )
addWorker(null, false);
}
//如果任务未能加入阻塞队列,则添加非核心线程 corePoolSize => maxPoolSize
//如果添加非核心线程也失败,开启拒绝策略
else if (!addWorker(command, false))
reject(command); //maxPoolSize => maxPoolSize
}

【详解】ThreadPoolExecutor源码阅读(三)的更多相关文章

  1. 【详解】ThreadPoolExecutor源码阅读(二)

    系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) AQS在W ...

  2. 【详解】ThreadPoolExecutor源码阅读(一)

    系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) 工作原理简 ...

  3. Android应用AsyncTask处理机制详解及源码分析

    1 背景 Android异步处理机制一直都是Android的一个核心,也是应用工程师面试的一个知识点.前面我们分析了Handler异步机制原理(不了解的可以阅读我的<Android异步消息处理机 ...

  4. 【转载】Android应用AsyncTask处理机制详解及源码分析

    [工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,尊重分享成果] 1 背景 Android异步处理机制一直都是Android的一个核心,也是应用工程师面试的一个 ...

  5. 线程池底层原理详解与源码分析(补充部分---ScheduledThreadPoolExecutor类分析)

    [1]前言 本篇幅是对 线程池底层原理详解与源码分析  的补充,默认你已经看完了上一篇对ThreadPoolExecutor类有了足够的了解. [2]ScheduledThreadPoolExecut ...

  6. 基于双向BiLstm神经网络的中文分词详解及源码

    基于双向BiLstm神经网络的中文分词详解及源码 基于双向BiLstm神经网络的中文分词详解及源码 1 标注序列 2 训练网络 3 Viterbi算法求解最优路径 4 keras代码讲解 最后 源代码 ...

  7. Java SPI机制实战详解及源码分析

    背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...

  8. select用法&原理详解(源码剖析)(转)

    今天遇到了在select()前后fd_set的变化问题,查了好久终于找到一个有用的帖子了,很赞,很详细!!原文链接如下: select用法&原理详解(源码剖析) 我的问题是: 如下图示:在se ...

  9. 详解ConCurrentHashMap源码(jdk1.8)

    ConCurrentHashMap是一个支持高并发集合,常用的集合之一,在jdk1.8中ConCurrentHashMap的结构和操作和HashMap都很类似: 数据结构基于数组+链表/红黑树. ge ...

随机推荐

  1. 20155326 第五周加分题--mybash的实现

    第五周加分题--mybash的实现 题目要求 1.使用fork,exec,wait实现mybash 2.写出伪代码,产品代码和测试代码 3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接) ...

  2. 微软新一代Surface发布,参数曝光

    在沉寂许久之后,Surface 2及Surface Pro 2又有猛料爆出,这一次不单单是新品展示,伴随的还有更多的详细的参数和全新配件. 从外观来看,新一代的Surface外形上沿袭了上一代,但颜色 ...

  3. node API

    看了这么久nodejs,它包含哪些基础的API,自己心中都没有数,该完整地看看基础的API了. 见过的: assert:编写程序的单元测试用例 buffer:直接处理2进制数据 child_proce ...

  4. centos下添加git

    CentOS中yum里没有Git,需要手动安装. 首先需要安装git的依赖包 yum install curl yum install curl-devel yum install zlib-deve ...

  5. poj 2676 如何填满九宫格

    Sudoku Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class ...

  6. ORACLE中的FTP例子代码

    http://blog.csdn.net/mashengwang/article/details/5982663 CREATE OR REPLACE DIRECTORY my_docs AS '/u0 ...

  7. Linux-帮助与基本命令

    1.获取命令帮助 Linux中的命令按可分类shell内嵌命令.外部命令,获取命令帮助信息前需要区分命令类型. 1.1 type - 查看命令类型 [root@VM_0_171_centos ~]# ...

  8. csv 文件读取(input)和截分(split)方法

    下面是宝玉对学生的指导

  9. 第5件事 做一个有taste的产品人

    1.taste的意思是品位,也就是说产品经理应该是一个有品位的产品人.什么叫品位呢?品位指的是对事物有分辨与鉴赏的能力.品位是形象的展示,品位是内在气质的复出,品位是人生价值的体验,品位是道德修养的内 ...

  10. 静态工厂 + DbHelper

    在 .NET 的学习过程中用过三种数据库:Sql Server.Access.SQLite.Sql Server 用得相对多一点点,但是,麻烦,每次用它都需要开服务,而且还费资源,更麻烦的是拷贝到一台 ...