概述
Core and maximum pool sizes
当有新的task通过execute方法提交。
1. 如果目前线程数 < corePoolSize,不论是否有空闲线程,这时都会创建一个新的线程来执行这个任务。
2. 如果corePoolSize < 目前线程数 < maximumPoolSize,只有当队列满了之后才会创建新线程
Creating new threads
使用ThreadFacotry来创建线程,该类有默认实现,其创建的线程都在同一个Group,并且优先级都一样
Keep-alive times
如果当前线程池中的线程数量 > corePoolSize,如果超出线程的空闲时间 > keepAliveTime,这些线程将被terminated。如果之后线程数量不够,那么还会再创建。设置allowCoreThreadTimeOut变量为true,也可以将keepAliveTime作用到core threads上。
Queuing
阻塞队列可以用来转移或接收task。
1. 如果目前线程 < corePoolSize,那么线程池会增加线程,而不是将task放入队列。
2. 如果当前线程 >= corePoolSize,那么线程池会将task放入队列,而不是增加线程。
3. 新task无法再加入队列(队列满了),如果目前线程 < maximumPoolSize,则会新增线程;否则会拒绝该task。
对于队列,一般有如下3中策略:
1. Direct handoffs(直接获取):这种策略适合使用SynchronousQueue,当有task来的适合,就会有线程立马处理;如果此时没有空闲线程,那么就会fail,于是会创建一个新的线程来处理这个task。这种策略的好处是,能避免因为任务间的依赖而造成线程处理的停顿。这种策略一般来说需要一个无界队列来防止task被拒绝,但是如果task来的比处理快时,队列会一致增大。
2. Unbounded queues(无界队列):一般采用LinkedBlockingQueue作为无界队列。当core thread都忙碌时,task会被放入队列,因为队列时无界的,因此线程数量不会超过corePoolSize。这种策略适合任务之间是无关的情况,如果页面请求。
3. Bounded queues(有界队列):一般采用ArrayBlockingQueue作为有界队列,它能防止task饿死,当队列满了之后,会创建新线程(当然数量不能超过maximumPoolSize)。当队列很大,但是maximumPoolSize较小的适合,CPU与资源使用率会较低,线程切换次数会增加,吞吐量会降低。当队列较小,maximumPoolSize较大时,CPU使用率会提高,但是新的task可能会被reject,因此也会降低吞吐量。
Rejected tasks
当1、线程池被关闭。2、队列满了,线程数量达到最大,由没有空闲线程的时候,新的任务会被rejected,此时会调用RejectedExecutionHandler,默认给出了4中策略:
1. ThreadPoolExecutor.AbortPolicy:当被reject时,抛出RejectedExecutionException。
2. ThreadPoolExecutor.CallerRunsPolicy:当被reject后,当前线程本身来执行之歌任务,不用线程池。
3. ThreadPoolExecutor.DiscardPolicy:直接丢弃。
4. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列中的队首任务,然后重试。
Hook methods
提供了beforeExecute以及afterExecute方法,它们分别在执行execute方法的前后执行。
源码
主要属性
public class ThreadPoolExecutor extends AbstractExecutorService {
/*
* RUNNING -> SHUTDOWN,通过执行shutdown()
* (RUNNING or SHUTDOWN) -> STOP,通过执行shutdownNow()
* SHUTDOWN -> TIDYING,当队列与线程池都为空
* STOP -> TIDYING,当线程池为空
* TIDYING -> TERMINATED,当terminated()执行结束
*/
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// 控制偏移量,头上3为控制状态
private static final int COUNT_BITS = Integer.SIZE - 3;
// 线程池的最大容量为2^29-1
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// 接收新task,处理队列中的task
private static final int RUNNING = -1 << COUNT_BITS;
// 不接受新的task,但是处理队列中的task
private static final int SHUTDOWN = 0 << COUNT_BITS;
// 不接受task,也不处理新的task
private static final int STOP = 1 << COUNT_BITS;
// 所有task都terminated,workerCount=0,执行terminated()方法
private static final int TIDYING = 2 << COUNT_BITS;
// terminated()已经完成
private static final int TERMINATED = 3 << COUNT_BITS;
// 表明线程是running、shuting down等状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 表明有效线程数
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
// 用于保存task,通过isEmpty()方法来判断队列是否为空
private final BlockingQueue<Runnable> workQueue;
// 当访问worker线程集时加锁
private final ReentrantLock mainLock = new ReentrantLock();
// 线程池中所有的worker threads,必须要获取mainLock才能访问这个集合
private final HashSet<Worker> workers = new HashSet<Worker>();
private final Condition termination = mainLock.newCondition();
// 线程池达到过的最大容量,必须要获取mainLock才能修改
private int largestPoolSize;
// 记录已经完成的任务数量,也要获取mainLock
private long completedTaskCount;
// 线程工程,用来new thread
private volatile ThreadFactory threadFactory;
// RejectedExecutionHandler,当task被reject时,执行这个handler
private volatile RejectedExecutionHandler handler;
// 非core thread保活时间
private volatile long keepAliveTime;
// core thread的保活时间
private volatile boolean allowCoreThreadTimeOut;
// 核心线程数量
private volatile int corePoolSize;
// 线程池可创建线程上限
private volatile int maximumPoolSize;
// 默认RejectedExecutionHandler
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
}
Worker源码
private final class Worker extends AbstractQueuedSynchronizer implements Runnable{
// 当前worker running的线程
final Thread thread;
// 要运行的任务
Runnable firstTask;
// 记录当前worker完成的task数量
volatile long completedTasks;
// 每次创建一个worker,都会新创建一个线程。
// 注意,这里初始化会把state设置为-1。当调用run,执行runWorker时,执行一步w.unlock();
// tryAcquire时对state进行cas(0,1),即只要state不是0,都是加锁状态。
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
// run方法调用runWorker方法
public void run() {
runWorker(this);
}
}
ThreadPoolExecutor源码
先看runWorker方法。
这个方法是执行task的主要方法,会反复地从队列中获取task并执行。
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
// 刚开始获取worker创建时初始化的firstTask
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // 将w的state从-1变成0,即释放锁,允许中断
boolean completedAbruptly = true;
try {
// 使用 || 运算,首次循环不会执行getTask(),之后会执行getTask()
while (task != null || (task = getTask()) != null) {
w.lock();
// 如果线程池时stopping状态,确保线程是中断的。
// 如果不是stopping状态,确保线程不是中断
// 采用双重检查来应对清楚中断过程中发生二次中断。Thread.interrupted()方法会重置中断
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
// beforeExecute方法是Hook method,如果有需要可以重写。
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 new Error(x);
} finally {
// afterExecute方法是Hook method,如果有需要可以重写。
afterExecute(task, thrown);
}
} finally {
// 让task=null,从而调用个while的getTask方法
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
getTask方法
以阻塞或time wait的形式来获取任务。
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
// 自旋
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// rs >= SHUTDOWN,那么可能是SHUTDOWN、STOP、TIDYING、TERMINATED等状态,这些状态都不接受task
//
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
// 使用cas的方式将workerCount-1
decrementWorkerCount();
return null;
}
// 当前线程数量
int wc = workerCountOf(c);
// core thread是否有timeout 或 当前线程数量有没有超过corePoolSize
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// 如果当前线程数量 > maximumPoolSize 或 超时了,那么就将当前worker干掉。
// 返回null,当前线程就会退出,详见runWorker的while循环
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
// 如果timed=ture,那么获取任务的时候,使用poll方法,如果在规定时间内没有任务,就会返回null
// 否则,会一直等带任务。
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
processWorkerExit方法
当worker线程被回收前执行,主要是做最后的清理工作
private void processWorkerExit(Worker w, boolean completedAbruptly) {
// 如果completedAbruptly为true,那就代表当前线程发生了异常,推测基本是因为interupt。从而补上原本
// 应该在getTask方法中的decrementWorkerCount。
if (completedAbruptly)
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 统计w Worker完成的任务数量,并将它从workers队列中移除
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
// 如果线程池还是running状态,那么当前线程可能是因为task的异常,那么再通过addWorker方法,加一个线程进去
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {//如果线程数量足够,那就不需要加线程。
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}
addWorker增加一个worker。
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {//又是自旋
int c = ctl.get();
int rs = runStateOf(c);
// 如果线程池的state不是running,或这shutdown的时候work队列为空,即没任务,那此时也不需要创建线程。
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(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // 预检查一次,如果此时新创建的线程已经start,说明有问题。
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
// 如果workerStarted=false,回滚。回滚就是吧w从wokers中移除,并且将workerCount-1
addWorkerFailed(w);
}
return workerStarted;
}