ThreadPoolExecuotor源码参考
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源码参考的更多相关文章
- vector源码(参考STL源码--侯捷):空间分配导致迭代器失效
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...
- renren-fast后端源码参考-配置和对应工具
1. renren-fast后端源码参考-配置和对应工具 1.1. 前言 renren-fast是个开源的前后端分离快速开放平台,没有自己框架的同学可以直接使用它的,而我打算浏览一遍它的代码,提取一些 ...
- 07_gitee源码参考
Django REST framework Tutorial 教程 码云:https://gitee.com/venicid/tutorial-api
- 异常定义-Mybatis中的源码参考
public class IbatisException extends RuntimeException { private static final long serialVersionUID = ...
- vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷):空间分配.push_back vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 v ...
- vector源码2(参考STL源码--侯捷):空间分配、push_back
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...
- vector源码1(参考STL源码--侯捷):源码
vector源码1(参考STL源码--侯捷) vector源码2(参考STL源码--侯捷) vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效 vector源码3(参考STL源 ...
- 分享一个单点登录、OAuth2.0授权系统源码(SimpleSSO)
SimpleSSO 关于OAuth 2.0介绍: http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 系统效果: 登录界面: 首页: 应用界面: ...
- hadoop-2.6.0-src源码导入Eclipse 转载
转载地址:http://m.blog.csdn.net/blog/le119126/42009281 一.导入 先修改源码 参考 二.改错里面的第3条 1.cd到 hadoop-2.6.0-src/h ...
随机推荐
- DELPHI 调试IOS时出现 Please specify exact device preset UUID
右击设备DEVICE, 选择REFRESH刷新, 再重新选择一个设备即可.
- 使用代理IP、高匿IP、连接失败
先百度一下,什么是代理IP 我们使用代理IP就是因为某些站点会屏蔽我们的IP,所以我们要动态的更换代理IP. 代理IP: 其中我们首先选择国内的IP,国外的一般都比较慢,其次不要选择如{新疆乌鲁木齐} ...
- 【CDN+】 一些常用的Linux命令,crontab+VI+Hive(持续更新)
前言 本文主要是记录下工作中可能用到的一些linux指令,当作字典查用 Crontab 基本命令 # 安装 yum -y install vixie-cron crontabs#查看状态 servic ...
- MIME TYPE是什么?
首先,我们要了解浏览器是如何处理内容的.在浏览器中显示的内容有 HTML.有 XML.有 GIF.还有 Flash ……那么,浏览器是如何区分它们,决定什么内容用什么形式来显示呢?答案是 MIME T ...
- win2019
slmgr /upkslmgr /ipk N69G4-B89J2-4G8F4-WWYCC-J464Cslmgr /skms zh.us.toslmgr /ato
- Jenkins+GitLab持续集成
向GitLab提交代码之后自动触发Jenkins构建 https://baijiahao.baidu.com/s?id=1630678692475452408&wfr=spider&f ...
- 经常用到的meta标签的整理
1.设置页面关键词<meta name="keywords" content="输入具体的关键词">2.设置页面的描述<meta name=& ...
- Entity Framework Code First数据库连接 转载 https://www.cnblogs.com/libingql/p/3351275.html
Entity Framework Code First数据库连接 1. 安装Entity Framework 使用NuGet安装Entity Framework程序包:工具->库程序包管理器 ...
- 使用 Vagrant 搭建 Kubernetes 本地测试环境
Vagrant 中文资料 参考资料 Kubernetes 需要一个至少包含三个节点的分布式系统.如果想学习 Kubernetes,或只是在本地搭建测试环境,则可以通过 Vagrant 来简单的实现. ...
- vlan trunk配置
vlan trunk配置 Trunk:中继干道 作用:一条链路能承载多个vlan的流量,并对不同vlan的流量进行不同标记 trunk能够使vlan跨越交换机 PT配置 配置vlan:两台交换机同样的 ...