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. linux下将一系列.o文件打包成.a文件

    参考链接:https://www.cnblogs.com/joshtao/p/7380627.html

  2. Flink 实战:如何解决生产环境中的技术难题?

    大数据作为未来技术的基石已成为国家基础性战略资源,挖掘数据无穷潜力,将算力推至极致是整个社会面临的挑战与难题. Apache Flink 作为业界公认为最好的流计算引擎,不仅仅局限于做流处理,而是一套 ...

  3. 小米笔记本pro版bios经常找不到硬盘

    自从买了小米笔记本,对小米的印象大大折扣,bios经常找不到硬盘,关机,重启,就好了. 到小米售后,售后说是系统坏了,我说bios里都找不到.他说,系统坏了也会出现这个情况.我说好吧.重做后,没用几天 ...

  4. if和switch的选择结构

    1. Java中的if选择结构,包括以下形式. *基本if选择结构:可以处理一单一或组合条件的情况. *if-else选择结构:可以处理简单的条件分支情况. *多重if选择结构:可以处理连续区间的条件 ...

  5. 破解Revealapp的试用时间限制

    转载自:http://jingwei6.me/2014/02/28/reveal_crack.html Revealapp作为分析iOS app UI结构的利器,还是非常称手的,89刀的价格也是物有所 ...

  6. (转)【mysql元数据库】使用information_schema.tables查询数据库和数据表信息 ---数据记录大小统计

    转:https://www.cnblogs.com/ssslinppp/p/6178636.html https://segmentfault.com/q/1010000007268994?_ea=1 ...

  7. linux暴露端口可以被外部访问

    linux暴露端口可以被外部访问,把端口号换成要暴露的端口:/sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT Centos 7 开启端口Cen ...

  8. CentOS 7命令行安装GNOME、KDE图形界面(成功安装验证)

    来源:cnblogs.com/Amedeo  作者:Amedeo 正文 CentOS 7 默认是没有图形化界面的,但我们很多人在习惯了 Windows 的图形化界面之后,总是希望有一个图形化界面从而方 ...

  9. Discuz升级 Database Error : pre_common_syscache ADD PRIMARY KEY (cname)【解决办法】

    错误码: 1068Multiple primary key defined Execution Time : 00:00:00:000Transfer Time : 00:00:00:000Total ...

  10. Go-内存To Be

    做一个快乐的互联网搬运工- 逃逸分析 逃逸分析的概念 在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法——分析在程序的哪些地方可以访问到指针. 它涉及到指针分析和形状分析. 当一个变量(或对 ...