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 ...
随机推荐
- chrles设置断点
1.选择你要断点的接口,右键Breakpoints 2.配置断点接口proxy>Breakpoint settings query设置为* 3.开始断点,重新抓取接口 修改入参.请求头 修改出参 ...
- iOS取消按钮点击时的动画效果
当存在图片或者背景图片时,点击图片往往意味着高亮,但是高亮的同时往往还伴随着按钮按下的动画效果,取消这种动画效果只需两步 Btn.adjustImageWhenHighlighted =NO; [Bt ...
- flume(2)
接续上一篇:https://www.cnblogs.com/metianzing/p/9511852.html 这里也是主要记录配置文件. 以上一篇案例五为基础,考虑到日志服务器和采集日志的服务器往往 ...
- MySQL5.7在Ubuntu上的安装、配置与使用
前言 服务器上安装东西一直是很让我头疼的事情,缘由:Linux基础不好.. 安装MySQL踩了很多坑,绕了很多弯路,这次踩得是tar包安装的坑... 当然,与tar包无关... 环境: Ubuntu ...
- html、css、js分工,内核,html头,html表单
html:内容css:样式js:交互 内核 浏览器控制台输入navigator.userAgent,回车显示出内核"Mozilla/5.0 (Windows NT 6.1; WOW64) A ...
- 移动端调试 — Pure|微信环境调试方案|App环境调试方案
Pure 详细参见: 中文文档:http://leeluolee.github.io/2014/10/24/use-puer-helpus-developer-frontend/ 源码:https:/ ...
- elasticsearch安装分词插件
在常用的中文分词器.拼音分词器.繁简体转换插件.国内用的就多的分别是:elasticsearch-analysis-ikelasticsearch-analysis-pinyinelasticsear ...
- Jexus 強勁、堅固、免費、易用的Linux ASP.NET服務器
Jexus 強勁.堅固.免費.易用的Linux ASP.NET服務器 Jexus是一款Linux平台上的高性能WEB服务器和负载均衡网关,以支持ASP.NET.ASP.NET CORE.PHP为特色, ...
- ETCD 简介及基本用法
ETCD 项目地址 ETCD 官方文档 1. 简介 ETCD 是一个高可用的分布式键值数据库,可用于服务发现.ETCD 采用 raft 一致性算法,基于 Go 语言实现. 特点 简单:安装配置使用简单 ...
- python实现获取文件夹中的最新文件
实现代码如下: #查找某目录中的最新文件import osclass FindNewFile: def find_NewFile(self,path): #获取文件夹中的所有文件 lists = os ...