什么是线程池
线程池的状态
线程池ThreadPoolExector 中有个院子变量:
高三位存储的是线程的状态,其他位存储线程数量
AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING,0))
//29位 int的位数 减三
int COUNT_BITS = Integer.SIZE - 3;
// 2^29-1 大约5亿1
int CAPACITY = (1 << COUNT_BITS) - 1;
// Packing and unpacking ctl 打包和解包ctl
int runStateOf(int c) { return c & ~CAPACITY; }
int workerCountOf(int c) { return c & CAPACITY; }
// 线程运行状态 和 线程数 返回ctl的值
int ctlOf(int rs, int wc) { return rs | wc; }
五种状态
// runState is stored in the high-order bits 从小到大排列
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
线程池的四种拒绝策略
这四个策略均实现了接口:RejectedExecutionHandler
通过 void rejectedExecution(Runnable r, ThreadPoolExecutor executor);方法来处理超出容量的线程。
默认的拒绝策略:
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
线程池的创建方式
ThreadPoolExector源码解析
类结构
ExecutorService 和Executor 都是接口只是定义了方法具体的实现在AbstractExecutorService 和 ThreadPoolExecutor中
简介
ThreadPoolExecutor 主体由两部分组成:
- 组成线程池的任务集合
// 用来保证workers 的安全,shutdown 和 shutdownNow时也用的到
private final ReentrantLock mainLock = new ReentrantLock();
//Set containing all worker threads in pool. Accessed only when holding mainLock.
//包含池中所有工作线程的集合,仅在持有mainLock时访问。
private final HashSet<Worker> workers = new HashSet<Worker>();
- 保存任务的队列
//用于保存任务和移交给工作线程的队列
private final BlockingQueue<Runnable> workQueue;
Worker 介绍
worker 类结构
Worker 是ThreadPoolExecutor的内部类。
worker实现了Runnable接口,自己本身就是一个线程。
worker继承了AbstractQueuedSynchronizer 同步器
worker中的变量
/** Thread this worker is running in. Null if factory fails. */
//运行任务的线程
final Thread thread;
/** Initial task to run. Possibly null. */
//正式运行的任务,可能为null
Runnable firstTask;
/** Per-thread task counter */
//线程的任务计数器
volatile long completedTasks;
构造方法
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
由构造方法可以看出thread就是当前的worker。
run方法
public void run() {
runWorker(this);
}
run方法调用了外部的ThreadPoolExecutor的 runWorker方法
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
//用来标识,完成任务前有没有被终止
boolean completedAbruptly = true;
try {
//在task=null时,会通过getTask()方法从线程池中获取task
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
//预留方法
beforeExecute(wt, task);
Throwable thrown = null;
try {
// 调用任务的run方法
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
// 预留方法
afterExecute(task, thrown);
}
} finally {
//任务执行完成,清空工人的任务
task = null;
// 为当前工人的任务数+1
w.completedTasks++;
w.unlock();
}
}
//完成任务前没有被终止
completedAbruptly = false;
} finally {
//回收工人的方法
processWorkerExit(w, completedAbruptly);
}
}
processWorkerExit 回收工人的方法
/**
清理垂死的工人,并进行登记。仅从工作线程调用。
w: 工人
completedAbruptly: 工人是否因为用户异常而死亡
**/
private void processWorkerExit(Worker w, boolean completedAbruptly) {
// 如果因为用户异常导致线程退出 则任务数量减一
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//将工人完成的任务数给总任务数
completedTaskCount += w.completedTasks;
//将工人从工人集合中移除
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
// 线程池为运行状态 或 shutdown状态
if (runStateLessThan(c, STOP)) {
//不是用户异常导致的工人死亡
if (!completedAbruptly) {
//如果允许核心线程长期存活 min= corPoolSize 否则为0
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
//不允许核心线程长期存活,且 队列为空 则 min = 1
if (min == 0 && ! workQueue.isEmpty())
min = 1;
// 工人数量 >= min 不用创建工人
if (workerCountOf(c) >= min)
return; // replacement not needed
}
// 如果是用户异常导致的退出 新建线程
// 如果工人正产死亡,且人工数量小于核心线程数 新建工人
addWorker(null, false);
}
}