关于ThreadPoolExecutor的解析
来源:互联网 发布:冒险岛怪物数据库 编辑:程序博客网 时间:2024/05/02 04:26
if (command == null)
throw new NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
else if (!addIfUnderMaximumPoolSize(command))
reject(command); // is shutdown or saturated
}
}
上面是源代码,首先说说poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)这句话说明如果线程数小于corePoolSize ,就会调用addIfUnderCorePoolSize(command),源码如下:
private boolean addIfUnderCorePoolSize(Runnable firstTask) {
Thread t = null;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (poolSize < corePoolSize && runState == RUNNING)
t = addThread(firstTask);
} finally {
mainLock.unlock();
}
if (t == null)
return false;
t.start();
return true;
}
其实就是直接创建新线程执行任务。如果线程数大于或者等于corePoolSize 的话就先插入队列,如果插入队列成功,由于这些判断不是在lock锁里面判断的,所以插入成功之后再次检查runState状态和poolSize数量。如果runState != RUNNING || poolSize == 0则说明两种情况,两种情况的源码处理如下:
private void ensureQueuedTaskHandled(Runnable command) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
boolean reject = false;
Thread t = null;
try {
int state = runState;
if (state != RUNNING && workQueue.remove(command))
reject = true;
else if (state < STOP &&
poolSize < Math.max(corePoolSize, 1) &&
!workQueue.isEmpty())
t = addThread(null);
} finally {
mainLock.unlock();
}
if (reject)
reject(command);
else if (t != null)
t.start();
}
第一种情况是插入队列之后,runState状态已经不是running,这样的话,如果任务还在workQueue中,workQueue.remove(command)成功,拒绝执行command;一种是插入队列之后,runState为running,但是线程池没有存活的线程。这样的话,在保证 poolSize < Math.max(corePoolSize, 1) 以及workQueue不为空,需要新建一个新线程来执行完workQueue中的任务。有人肯定会问那如果runState是shutDown状态,然后workQueue中又没有command的情况,我觉得这种情况很少,就算出现了,也不会有问题,要使workQueue不存在command只有两种情况,一种是被getTask执行掉了,一种是shutDownNow把workQueue清空了,但是时间间隙这么少基本上不会出现,就算出现了,也会走第二种情况不会出现问题。
继续上面的讲解,如果poolSize >= corePoolSize而且 command又无法加入workQueue,这样的话会执行addIfUnderMaximumPoolSize,源码如下
private boolean addIfUnderMaximumPoolSize(Runnable firstTask) {
Thread t = null;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (poolSize < maximumPoolSize && runState == RUNNING)
t = addThread(firstTask);
} finally {
mainLock.unlock();
}
if (t == null)
return false;
t.start();
return true;
}
上面的代码和addIfUnderCorePoolSize一模一样就是判断poolSize是否小于maximumPoolSize ,如果是,就新建线程执行command.否则就会调用 reject(command),拒绝任务。
- 关于ThreadPoolExecutor的解析
- 解析ThreadPoolExecutor
- 解析ThreadPoolExecutor
- ThreadPoolExecutor解析
- 关于ThreadPoolExecutor
- 关于ThreadPoolExecutor 调用RejectedExecutionHandler的机制
- ThreadPoolExecutor代码解析
- ThreadPoolExecutor代码解析
- ThreadPoolExecutor源码解析
- ThreadPoolExecutor源码解析
- ThreadPoolExecutor源码解析
- ThreadPoolExecutor源码解析
- ThreadPoolExecutor源码解析
- ThreadPoolExecutor源码解析
- ThreadPoolExecutor源码解析
- ThreadPoolExecutor线程池解析与BlockingQueue的三种实现
- 关于ThreadPoolExecutor使用介绍
- 关于myeclipse 总是弹出ThreadPoolExecutor 窗口的解决办法
- 橱窗的魔幻世界
- 关于POX中的lib.revent.py阅读分析
- 浅述道路护栏的设计要求
- 计算机电脑账户为来宾账户,又不知道管理员密码,进入来宾账户操作权限受限
- 关于 hosts DNS解析
- 关于ThreadPoolExecutor的解析
- R:Operator Syntax and Precedence
- ORA-00600
- HDU 1848 Fibonacci again and again 博弈论SG函数
- 在键盘上加自定义 按钮
- android:windowSoftInputMode属性详解
- cocos2d-x使用tinyxml2解析&存储xml
- QML基础——UI布局管理
- 【cocos2d-x游戏开发】触摸事件