Executor -->  ExecutorService  -->  AbstractExecutorService --> ThreadPoolExecuotor

Executor接口,只有一个execute方法,参数为线程任务

ExecutorService接口继承Executor接口,增加了submit、shutdown、invokeAll等方法

AbstractExecutorService抽象类,实现ExecutorService接口,提供了submit、invokeAny、invokeAll默认实现方法, execute、
shutdown、shutdownNow等待没有提供默认的实现 ThreadPoolExecutor 线程池状态值
---RUNNING 接受新任务并且处理阻塞队列里的任务
---SHUTDOWN 拒绝信任务但是处理阻塞队列里的任务
---STOP 拒绝新任务并且抛弃阻塞队列里的任务同时会中断正在处理的任务
---TIDYING 所有任务都执行完当前线程池活动线程为0,将调用terminated方法
---TERMINATED 终止状态 构造函数
---有四个构造函数,其他三个都是调用下面这个构造函数
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {}
---参数说明
corePoolSize 核心线程数
maximumPoolSize 最大线程数
keepAliveTime 存活时间
unit 时间单位
workQueue 存放线程的队列
threadFactory 创建线程的工厂
handler 拒绝策略 提交任务
---submit
public Future<?> submit(Runable task) {
if(task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if(task == null) throw new NullPointerExecetion();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if(task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
--- execute
public void execute(Runnable command) {
if(command == null)
throw new NullPointerException();
//获取当前线程池的状态+线程个数
int c = ctl.get();
//判断当前线程池数量是否小于corePoolSize,小于则调用addWorker方法创建新线程运行,且传进来的Runnable当做第一个任务执行
if(workerCountOf(c) < corePoolSize) {
if(addWorker(command, true))
return;
c = ctl.get();
} //如果线程池处于Running状态,则添加任务到阻塞队列
if(isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//如果当前线程池状态不是Running则从队列删除任务,并执行拒绝策略
if(!isRunning(recheck) && remove(command))
reject(command);
//如果当前线程池为空,则添加一个线程
else if(workercountOf(recheck) == 0)
addWorker(null, false);
}
//新增线程失败则执行拒绝策略
else if(!addWorker(command, false))
reject(command);
} ---addWorker
private boolean addWorder(Runnable firstTask, boolean core) {
retry:
for(;;) {
int c = ctl.get();
int rs = runStateOf(c);
//检查当前线程池状态是否是shutdown、stop、tidying、terminated且!(当前状态为shutdown、传入的任务为null、队列不为null),条件都成立时返回false
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false; for(;;) {
int wc = workerCountOf(c);
if(wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize) )
return false;
if(compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get();
if(runStateOf(c) != rs)
continue retry;
}
} boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try{
// new thread
w = new Worker(firstTask);
final Thread t = w.thread();
if(t != null) {
//lock
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try{
//check thread pool state
int rs = runStateOf(ctl.get());
if(rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null) ) {
//检查线程是否可启动
if(t.isAlive())
throw new IllegalThreadStateException();
workers.add(w) ;
int s = workers.size();
if(s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
}finally {
mainLock.unlock();
}
//判断worker是否添加成功,成功则启动线程,将workerStarted设置为true
if(workerAdded) {
t.start();
workerStarted = true;
}
}
}finally{
if(!workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
---runWorker,线程启动时调用了runWorker方法
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock();
boolean completedAbruptly = true;
try {
//循环获取任务
while(task != null || (task = getTask()) != null ) {
w.lock();
// 当线程池是处于STOP状态或者TIDYING、TERMINATED状态时,设置当前线程处于中断状态
// 如果不是,当前线程就处于RUNNING或者SHUTDOWN状态,确保当前线程不处于中断状态
// 重新检查当前线程池的状态是否大于等于STOP状态
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
}catch(RuntimeException x) {
thrown = x; throw x;
}catch(Error x) {
thrown = x; throw x;
}catch(Throwable x) {
thrown = x; throw Error(x);
}finally {
afterExecute(taskm thrown);
}
}finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
}finally {
processWokerExit(w, completedAbruptly);
}
} ---getTask
private Runnable getTask() {
boolean timeOut = false;
for(;;) {
int c = ctl.get();
int rs = runStateOf(c); if(rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty() )) {
decrementWorkerCount();
return null;
}
int wc = workerCountof(c);
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
//(当前线程数是否大于最大线程数或者)
//且(线程数大于1或者任务队列为空)
//这里有个问题(timed && timedOut)timedOut = false,好像(timed && timedOut)一直都是false吧
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try{
Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
if(r != null)
return r;
timedOut = true;
}catch(InterruptedException retry) {
timedOut = false;
}
}
} ---shutdown 关闭线程池
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try{
checkShutdownAccess();
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
onShutdown();
}finally{
mainLock.unlock();
}
tryTerminate();
}

ThreadPoolExecuotor源码参考的更多相关文章

  1. vector源码(参考STL源码--侯捷):空间分配导致迭代器失效

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...

  2. renren-fast后端源码参考-配置和对应工具

    1. renren-fast后端源码参考-配置和对应工具 1.1. 前言 renren-fast是个开源的前后端分离快速开放平台,没有自己框架的同学可以直接使用它的,而我打算浏览一遍它的代码,提取一些 ...

  3. 07_gitee源码参考

    Django REST framework Tutorial 教程 码云:https://gitee.com/venicid/tutorial-api

  4. 异常定义-Mybatis中的源码参考

    public class IbatisException extends RuntimeException { private static final long serialVersionUID = ...

  5. vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷):空间分配.push_back vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 v ...

  6. vector源码2(参考STL源码--侯捷):空间分配、push_back

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...

  7. vector源码1(参考STL源码--侯捷):源码

    vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...

  8. 分享一个单点登录、OAuth2.0授权系统源码(SimpleSSO)

    SimpleSSO 关于OAuth 2.0介绍: http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 系统效果: 登录界面: 首页: 应用界面: ...

  9. hadoop-2.6.0-src源码导入Eclipse 转载

    转载地址:http://m.blog.csdn.net/blog/le119126/42009281 一.导入 先修改源码 参考 二.改错里面的第3条 1.cd到 hadoop-2.6.0-src/h ...

随机推荐

  1. 【ElicitSearch】启动流程

    一.集群启动流程 1.选举主节点 许多节点启动,集群干的第一件事儿就是选主,之后的的流程由主节点触发. 先确定唯一的.大家公认的主节点:再想办法把最新的及其原数据复制到选举的主节点上. 选主是对Bul ...

  2. php大文件断点续传

    该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开始. 如何分 ...

  3. 十二 windows临界区,其他各种mutex

    一.windows临界区 类似于互斥量 == 临界区. 二.多次进入临界区 进入临界区(加锁): 离开临界区(解锁): 同一个线程中windows中相同临界区变量代表的临界区进入(entercirti ...

  4. [CSP-S模拟测试]:Seat(概率DP+数学)

    题目描述 有$n+2$个座位等距地排成一排,从左到右编号为$0$至$n+1$.最开始时$0$号以及$n+1$号座位上已经坐了一个小$G$,接下来会有$n$个小$G$依次找一个空座位坐下.由于小$G$们 ...

  5. 面向对象编程思想(OOP)(转发)

    本文我将从面向对象编程思想是如何解决软件开发中各种疑难问题的角度,来讲述我们面向对象编程思想的理解,梳理面向对象四大基本特性.七大设计原则和23种设计模式之间的关系. 软件开发中疑难问题: 软件复杂庞 ...

  6. C-LeetCode-Shuffle an Array跑不过测试用例

    使用time()作为随机数种子,一秒改变一次随机数还是不够随机,跑不过测试用例6 ,在加上个毫秒级计时精度的clock()作为随机数种子就达标了. 示例代码: typedef struct { int ...

  7. 126、TensorFlow Session的执行

    # tf.Session.run 方法是一个执行tf.Operation或者计算tf.Tensor的一个主要的机制 # 你可以传递一个或者多个tf.Operation或者tf.Tensor对象来给tf ...

  8. ag-grid 表格中添加图片

    ag-grid是一种非常好用的表格,网上搜索会有各种各样的基本用法,不过对于在ag-grid 表格中添加图片我没有找到方法,看了官方的文档,当然英文的自己也是靠网页翻译,最后发现有这么一个例子,我知道 ...

  9. Mac环境搭建nginx服务器

    一 安装 1 安装Homebrew macOS 缺失的软件包的管理器,安装方法参考官网.(可能被墙) 2 安装nginx. brew install nginx 先更新homebrew.再安装ngin ...

  10. (appium+python)UI自动化_07_app UI自动化实例【叮咚搜索加车为例】

    前言 初学UI自动化的小伙伴,在配置好appium+python自动化环境后,往往不知道如何下手实现自动化.小编在初期学习的时候也有这种疑惑,在此以叮咚买菜app-搜索加车为实例,展示下appium是 ...