源码解读的注释都在代码中,有些重复的代码没有注释,如若有哪些地方我理解错了欢迎评论区留言或者私信我指正,成长的路上相互学习共同进步。
以下是ThreadPoolExecutor的所有源码,建议按照以下的顺序看
1、先了解ThreadPoolExecutor的常量
2、了解Worker内部类的结构
3、execute()方法
4、addWorker()方法
5、runWorker()方法
6、completedAbruptly()方法
7、processWorkerExit()方法
8、getTask()方法
9、shutdown()方法
10、shutdownnow()方法
11、tryTerminal()方法
除了这些方法,在阅读过程中涉及的其他方法自行移步读,基本都有相应解读
package Executor;
/**
* @author hejs
* @version 1.0
* @createDate 2022年03月02日 09:00
* @since JDK1.8
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* class PausableThreadPoolExecutor extends ThreadPoolExecutor {
* private boolean isPaused;
* private ReentrantLock pauseLock = new ReentrantLock();
* private Condition unpaused = pauseLock.newCondition();
*
* public PausableThreadPoolExecutor(...) { super(...); }
*
* protected void beforeExecute(Thread t, Runnable r) {
* super.beforeExecute(t, r);
* pauseLock.lock();
* try {
* while (isPaused) unpaused.await();
* } catch (InterruptedException ie) {
* t.interrupt();
* } finally {
* pauseLock.unlock();
* }
* }
*
* public void pause() {
* pauseLock.lock();
* try {
* isPaused = true;
* } finally {
* pauseLock.unlock();
* }
* }
*
* public void resume() {
* pauseLock.lock();
* try {
* isPaused = false;
* unpaused.signalAll();
* } finally {
* pauseLock.unlock();
* }
* }
* }}</pre>
*
* @since 1.5
* @author Doug Lea
*/
public class ThreadPoolExecutor extends AbstractExecutorService {
//用来标记线程池状态(高3位),线程个数(低29位)
//默认是RUNNING状态,线程个数为0
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//线程个数掩码位数,并不是所有平台int类型是32位,所以准确说是具体平台下Integer的二进制位数-3后的剩余位数才是线程的个数,
private static final int COUNT_BITS = Integer.SIZE - 3;
// CAPACITY 工作线程最大数量
//(底29位):00011111111111111111111111111111
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
//线程最大个数(低29位)00011111111111111111111111111111
//(高3位):11100000000000000000000000000000
//RUNNING:接受新任务并且处理阻塞队列里的任务;
private static final int RUNNING = -1 << COUNT_BITS;
//(高3位):00000000000000000000000000000000
//SHUTDOWN:拒绝新任务但是处理阻塞队列里的任务;
private static final int SHUTDOWN = 0 << COUNT_BITS;
//(高3位):00100000000000000000000000000000
//STOP:拒绝新任务并且抛弃阻塞队列里的任务,同时会中断正在处理的任务;
private static final int STOP = 1 << COUNT_BITS;
//(高3位):01000000000000000000000000000000
//TIDYING:所有任务都执行完(包含阻塞队列里面任务)当前线程池活动线程为 0,将要调用 terminated 方法;
private static final int TIDYING = 2 << COUNT_BITS;
//(高3位):01100000000000000000000000000000
//TERMINATED:终止状态,terminated方法调用完成以后的状态。
private static final int TERMINATED = 3 << COUNT_BITS;
// 获取高三位 运行状态
// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~COUNT_MASK; }
//获取低29位 工作线程个数
private static int workerCountOf(int c) { return c & COUNT_MASK; }
//计算ctl新值,线程状态 与 线程个数
private static int ctlOf(int rs, int wc) { return rs | wc; }
private static boolean runStateLessThan(int c, int s) {
return c < s;
}
private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}
private static boolean isRunning(int c) {
return c < SHUTDOWN;
}
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
private void decrementWorkerCount() {
ctl.addAndGet(-1);
}
private final BlockingQueue<Runnable> workQueue;
//独占锁,用于控制新增 Worker 线程时候的原子性
private final ReentrantLock mainLock = new ReentrantLock();
private final HashSet<ThreadPoolExecutor.Worker> workers = new HashSet<>();
//是mainLock锁对应的条件队列,在线程调用 awaitTermination 时候用来存放阻塞的线程
private final Condition termination = mainLock.newCondition();
private int largestPoolSize;
private long completedTaskCount;
private volatile ThreadFactory threadFactory;
private volatile RejectedExecutionHandler handler;
private volatile long keepAliveTime;
private volatile boolean allowCoreThreadTimeOut;
private volatile int corePoolSize;
private volatile int maximumPoolSize;
private static final RejectedExecutionHandler defaultHandler =
new ThreadPoolExecutor.AbortPolicy();
private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");
private final class Worker extends AbstractQueuedSynchronizer implements Runnable
{
private static final long serialVersionUID = 6138294804551838833L;
/** Thread this worker is running in. Null if factory fails. */
final Thread thread;
/** Initial task to run. Possibly null. */
Runnable firstTask;
/** Per-thread task counter */
volatile long completedTasks;
// TODO: switch to AbstractQueuedLongSynchronizer and move
// completedTasks into the lock word.
/**
* 使用线程工厂创建工作线程,发放任务给工作线程
* @param firstTask
*/
Worker(Runnable firstTask) {
//设置工作线程状态为-1,在真正执行任务前禁止中断
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/** Delegates main run loop to outer runWorker. */
@Override
public void run() {
runWorker(this);
}
// Lock methods
//
// The value 0 represents the unlocked state.
// The value 1 represents the locked state.
@Override
protected boolean isHeldExclusively() {
return getState() != 0;
}
@Override
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
/**
* 这里的加锁解锁的方法利用AQS中的state变量,-1表示禁止打断还未启动的线程,0表示没有线程持有锁 1,表示有线程持有锁
* 用于标记工作线程的空闲状态(空闲线程没加锁,加了锁的便不是空闲线程)
*/
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
/**
* 打断已经启动且没有被打断过的工作线程,打断过的线程不必再打断了(再打断就是多此一举)
* //被打断过的会在getTask那儿抛中断异常
*/
void interruptIfStarted() {
Thread t;
//运行状态大于0,表示还有启动的任务,便打断
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
/**
*修改线程池运行状态
* @param targetState
*/
private void advanceRunState(int targetState) {
// assert targetState == SHUTDOWN || targetState == STOP;
for (;;) {
int c = ctl.get();
//当前线程池状态已经是目标状态以上了,那么没必要进行修改,否者进行修改成功后返回,
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
/**
* 尝试终止线程池
* 如果线程池还有多个线程或者已经进入整理,或者
* 停止且任务队列为空,返回,说明有线程在做终止操作了
* 不需要自己在处理了,如果还有多个工作线程,减少一个空闲线程
* 如果线程池的工作线程为0了,
* 那么进入该方法的就是线程池唯一的线程,必须自己终止线程
*/
final void tryTerminate() {
for (;;) {
int c = ctl.get();
//如果线程池处于running状态,线程池是正常的 无需处理,返回,
//如果线程池处于整理状态 说明 已经有其它线程 在执行 TIDYING -> TERMINATED状态了 无需处理,返回
//如果线程池小于停止状态 但是 任务队列为空 这是SHUTDOWN的特殊情况,直接回去。得等队列中的任务处理完毕后,再转化状态。 无需处理,返回
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateLessThan(c, STOP) && ! workQueue.isEmpty()))
return;
//如果线程池中工作线程数量不为0,释放一个空闲工作线程
//其实就是通过中断信号,唤醒阻塞的线程(getTask()阻塞的)
//这里为什么只释放一个呢?
//因为tryTerminate方法多个方法都在调用,工作线程任务执行完后processWorkerExit里面也会调用,
// 所以每次执行完任务都会调用,所以每次都中断其中一个线程。
if (workerCountOf(c) != 0) { // Eligible to terminate
//释放一个空闲工作线程
interruptIdleWorkers(ONLY_ONE);
return;
}
//到这里说明是这是线程池中最后一个线程了,所以执行终止操作
//线程池最后一个线程执行终止线程池
final ReentrantLock mainLock = this.mainLock;
//获取线程池全局锁
mainLock.lock();
try {
//cas将运行状态设置为整理状态,工作线程为0
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
//钩子函数,按需重写,这里为空方法
terminated();
} finally {
//设置运行状态为终止状态
ctl.set(ctlOf(TERMINATED, 0));
//唤醒调用 awaitTermination() 方法的线程。
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
private void checkShutdownAccess() {
// assert mainLock.isHeldByCurrentThread();
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
for (ThreadPoolExecutor.Worker w : workers)
security.checkAccess(w.thread);
}
}
/**
* 打断所有已经启动的工作线程
*/
private void interruptWorkers() {
// assert mainLock.isHeldByCurrentThread();
for (ThreadPoolExecutor.Worker w : workers)
w.interruptIfStarted();
}
/**
* 释放空闲线程
* @param onlyOne
*/
private void interruptIdleWorkers(boolean onlyOne) {
//加锁,防止多个线程导致问题,shutdown虽然也加了锁再调用这个方法,
// 但是还有其他方法也调这个方法呢
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//如果不是要求释放一个空闲工作线程的话,将线程容器中的空闲线程释放掉
for (ThreadPoolExecutor.Worker w : workers) {
Thread t = w.thread;
//如果线程被中断过,不必再中断了,进入下一循环
// 如果线程没有被打断过,
// 并且获取到了锁(空闲线程在获取任务队列中的任务时是阻塞在get方法上,
// 取到了任务在加锁执行,所以在这里获取到了锁,说明是空闲线程,也就是阻塞在任务队列取任务的线程)
if (!t.isInterrupted() && w.tryLock()) {
//是空闲线程则设置打断标志位
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
//加锁后记得解锁
w.unlock();
}
}
//如果只要求释放一个线程,那么释放一个工作线程后结束循环
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
/**
* 没带参数,默认打断所有空闲线程
*/
private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}
private static final boolean ONLY_ONE = true;
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
void onShutdown() {
}
/**
* 取出任务队列中的所有任务
* @return
*/
private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
ArrayList<Runnable> taskList = new ArrayList<>();
//任务队列中还有任务,逐个取出放到容器中返回,取出就是拿出来,阻塞队列拿一个少一个
q.drainTo(taskList);
// 如果执行完drainTo后,q还不是空的
// 是因为,阻塞队列是延迟队列来的,延迟队列的话是不具备删除功能,需要手动取出
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}
/**
* 添加工作线程执行任务
* 调用该方法的情况
* 1、核心线程还未满,添加核心线程执行任务
* 2、核心线程满了,任务添加到阻塞队列添加成功了,但核心线程都超时了,
* 导致线程池中线程数为0,添加一个补尝线程执行任务;(前提是开启了核心线程超时销毁)
* 3、核心线程和阻塞队列都满了。则开启非核心线程来执行任务
* @param firstTask
* @param core
* @return
*/
private boolean addWorker(Runnable firstTask, boolean core) {
//此嵌套死循环执行成功的话只做了运行状态加1,即工作线程数加1,而非添加了工作线程
retry:
for (int c = ctl.get();;) {
// Check if queue empty only if necessary.
/**
* RUNNING:接受新任务 并且 处理 阻塞队列里的任务;
* SHUTDOWN:拒绝新任务 但是 处理 阻塞队列里的任务;
* STOP:拒绝新任务 并且 抛弃 阻塞队列里的任务,同时会 中断 正在处理的任务;
* TIDYING:所有任务都执行完(包含阻塞队列里面任务)当前线程池活动线程为 0,将要调用 terminated 方法;
* TERMINATED:终止状态,terminated方法调用完成以后的状态。
*/
if ( //线程池状态不为running状态,即为SHUTDOWN、STOP、TIDYING、TERMINATED中的一种
//该状态下要求不再接收新任务,如果后面判断也是true 则返回false execut()方法不做处理或者执行拒绝策略
runStateAtLeast(c, SHUTDOWN) &&
//线程池状态为STOP、TIDYING、TERMINATED中的一种,这些状态下不再处理任务,即使正在处理的线程也得中断
(runStateAtLeast(c, STOP)
//如果线程池状态为SHUTDOWN,且有提交的任务。则返回false
// 这里如果提交的任务为空,则是补充线程
|| firstTask != null
//如果线程池状态为SHUTDOWN,且提交的任务为空(补充线程),阻塞队列为空,则返回false
|| workQueue.isEmpty())
)
//返回false,execut()方法不做处理或者执行拒绝策略
return false;
//执行到这儿,有2种情况1:线程池处于running状态(接收新任务)
//2、线程池处于SHUTDOWN状态、提交的空任务(补充线程)
// 且阻塞队列不为空(即处于SHUTDOWN状态,还需继续执行阻塞队列的任务)
for (;;) {
//检查工作线程数
//如果加的是核心线程检查是否大于核心线程数
//如果加的是非核心线程,那么检查是否大于最大线程数
if (workerCountOf(c)
>= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
return false;
//到这儿说明可以加工作线程
//多线程下CAS尝试将工作线程数(运行状态)加1
if (compareAndIncrementWorkerCount(c))
//添加成功,结束外循环
break retry;
//到这儿说明有其他线程更改了运行状态(线程数量或运行状态),工作线程加1失败
//重新获取运行状态快照
c = ctl.get(); // Re-read ctl
//判断运行状态是不是running状态了,如果已经不是running状态了就回到外循环
if (runStateAtLeast(c, SHUTDOWN))
continue retry;
// 到这儿说明是线程数量发生了改变,再次执行内循环更改运行状态加1
}
}
//运行到这儿,说明ctl(运行状态)的工作线程数已成功加1了
//下面便是完成创建线程执行提交的任务
boolean workerStarted = false;//worker是否开始执行,也就是是否执行:t.start();
boolean workerAdded = false;// worker是否被加入到工作线程队列(HashSet)中
ThreadPoolExecutor.Worker w = null;
try {
//创建工作线程,并将任务发放给工作线程(只是创建,还没让其启动执行),work有个state为-1,即工作线程还未启动
w = new ThreadPoolExecutor.Worker(firstTask);
final Thread t = w.thread;
//工作线程创建成功,加独占锁。保证添加到工作线程到HashSet队列中是线程安全的操作
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 c = ctl.get();
//检查线程池运行状态,
if (isRunning(c) ||
//如果线程池处于SHUTDOWN状态并且提交的工作线程是空的(即是补充线程)那么添加工作线程
(runStateLessThan(c, STOP) && firstTask == null)) {
//校验线程的状态
if (t.isAlive()) // precheck that t is startable
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)
addWorkerFailed(w);
}
//返回添加成功或失败
return workerStarted;
}
/**
* 添加工作线程失败,从工作线程容器中移除,并减线程数量
* @param w
*/
private void addWorkerFailed(ThreadPoolExecutor.Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
//从工作线程容器中移除
workers.remove(w);
//ctl线程数减1
decrementWorkerCount();
//尝试终止线程池
tryTerminate();
} finally {
mainLock.unlock();
}
}
/**
* 将运行结束后的工作线程移出HashSet队列,再补充一个空线程进去
* @param w
* @param completedAbruptly
*/
private void processWorkerExit(ThreadPoolExecutor.Worker w, boolean completedAbruptly) {
//如果是任务执行过程中发生了错误,cas减少工作线程数
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
//加锁,保证工作线程移出队列的安全性
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
//将工作线程移出HashSet队列
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
//如果线程池是RUNNING或者SHUTDOWN状态
if (runStateLessThan(c, STOP)) {
//如果任务顺利完成(completedAbruptly=false)
if (!completedAbruptly) {
//判断是否设置了允许核心线程超时
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
//如果设置了核心线程允许超时,且阻塞队列还有任务
if (min == 0 && ! workQueue.isEmpty())
min = 1;
//工作线程保证至少还有一个来执行任务,有就返回,否者继续往下执行,添加一个工作线程(补偿)
if (workerCountOf(c) >= min)
return; // replacement not needed
}
//总结上面if判断:如果线程池是RUNNING或者SHUTDOWN状态,且任务队列不是空,那么至少保证线程池中有一个线程在执行任务
addWorker(null, false);
}
}
/**
* 从阻塞队列中获取任务
* 如果工作线程没设置超时,那么会一直阻塞在获取任务这儿
* 如果设置了,一旦超时,那么便会使工作线程结束其生命周期
* @return
*/
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
//如果线程池状态不能再接收任务了,并且 (线程池状态也不能执行任务了或者阻塞队列已经空了)
//总结:1、如果线程状态大于STOP,即不再执行任务,工作线程不必在阻塞在获取任务这儿了
// 2、如果线程池状态为SHUTDOWN并且线程池为空,工作线程也不必再阻塞在获取任务这儿了,因为也不会接收新任务了
if (runStateAtLeast(c, SHUTDOWN)
&& (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
//工作线程减1并返回空
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// 是否允许核心线程超时,允许,返回true,线程活跃数超过核心线程数也返回true
//总结:1、活跃线程数大于核心线程数(大于1),减少工作线程数到核心线程的个数
// 2、活跃线程数不大于核心线程数了
// 2.1、设置了允许核心线程数超时,并且获取任务超时了
// 工作队列一直为空 那么减少工作线程数直至为0,不为空,就直至只有一个工作线程
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
//如果活跃线程数大于核心线程数,或者允许超时且已经超时
if ((wc > maximumPoolSize || (timed && timedOut))
//活跃线程数大于1或者阻塞队列为空
&& (wc > 1 || workQueue.isEmpty())) {
//减少工作线程数
if (compareAndDecrementWorkerCount(c))
return null;
//减少失败再次循环减
continue;
}
//timed是true,执行workQueue.poll()也就是设置获取任务的超时时间,
// 到时间后还没获取到任务的话则会timeOut=true。
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
//timed为false,那么工作线程会一直阻塞在这儿,直到获取到一个任务
workQueue.take();
//获取到任务返回
if (r != null)
return r;
//timeOut=true的话,getTask会让其跳出循环,线程生命周期便会结束。
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
/**
* 工作线程执行任务
* @param w
*/
final void runWorker(ThreadPoolExecutor.Worker w) {
Thread wt = Thread.currentThread();
//获取添加工作线程时分配的任务,如果task为空则工作线程已经执行了添加工作线程时的任务,再次执行的话就得从任务队列中取了
Runnable task = w.firstTask;
w.firstTask = null;
// 之前设置线程还未启动的时候state为-1,禁止打断,
// 这里恢复为0,表示运行过程中可以打断
w.unlock();
boolean completedAbruptly = true;
try {
//任务不为空,便执行任务(注意:这里是有任务才加锁执行)
//否者从阻塞队列中取任务,如果阻塞队列没任务,那么一直阻塞在这儿
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
// 如果线程池状态是大于等于STOP(执行了shutdownNow),
// 并且当前线程没有被中断过的(!wt.isInterrupted()),则让线程中断,
// STOP状态要求运行的线程也会中断
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
//如果线程池处于还能运行任务的状态(running、shutdown)那么执行任务
try {
/**
* 线程任务开始执行前做一些处理,可以自定义实现方法。模板方法。
* 需要注意的地方是该方法只被try finally包起来了,没有catch,
* 也就是说异常会被吞,即使报错,如果用户不做catch捕获的话,
* 也不会影响线程下面的工作
*/
beforeExecute(wt, task);
try {
task.run();
/**
* 线程任务开始执行后做一些处理,可以自定义实现方法。模板方法。
* 需要注意的地方是该方法只被try finally包起来了,没有catch,
* 也就是说异常会被吞,即使报错,如果用户不做catch捕获的话,
* 也不会影响线程下面的工作
*/
afterExecute(task, null);
} catch (Throwable ex) {
/**
* 线程任务开始执行后做一些处理,可以自定义实现方法。模板方法。
* 需要注意的地方是该方法只被try finally包起来了,没有catch,
* 也就是说异常会被吞,即使报错,如果用户不做catch捕获的话,
* 也不会影响线程下面的工作
*/
afterExecute(task, ex);
throw ex;
}
} finally {
//执行完后将任务置空,回到循环等待从阻塞队列中获取任务
task = null;
//执行完后,完成任务加1
w.completedTasks++;
//解锁,用于判断线程是否是空闲,
w.unlock();
}
}
//执行任务正常才置为false,如果发生异常则是默认的true,这里发生的异常基本上都是重写那两个模板方法中出现的
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
/**
* 根据线程池状态将任务 添加进阻塞队列
* 还是 创建线程执行 还是 执行拒绝策略
* @param command
*/
@Override
public void execute(Runnable command) {
//如果任务为空,抛出异常
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//如果线程池的工作线程小于核心线程 就新建工作线程执行任务
if (workerCountOf(c) < corePoolSize) {
//添加工作线程
if (addWorker(command, true))
return;
//更新运行状态快照
c = ctl.get();
}
//到这儿说明核心线程已经满了,再来任务将放到任务队列了
//如果现称池是运行状态,尝试将任务添加到任务队列
if (isRunning(c) && workQueue.offer(command)) {
//添加到任务队列成功,再次检查运行状态
int recheck = ctl.get();
//如果线程池被其他线程关闭了,那么就将刚才添加的任务移除掉
if (! isRunning(recheck) && remove(command))
//线程池关闭,并且当前任务从任务队列中移除成功,执行当前任务执行拒绝策略
reject(command);
//到这儿说明线程池是running状态或者移除任务失败,并且任务添加任务队列成功
//检查工作线程数是不是为0,为0,就添加一个工作线程进行补偿
//(为0是因为核心线程允许超时销毁,此时刚好线程都销毁了)
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//到这儿说明核心线程数满了,任务队列也满了,
// 如果还有任务提交就尝试添加非核心线程执行任务
else if (!addWorker(command, false))
//尝试添加非核心线程执行任务失败,说明已经到达最大线程数及任务队列已经满了,则执行拒绝策略
reject(command);
}
/**
* 关闭线程池
* 提供有钩子函数onShutdown(),shutdownnow()方法没有
* shutdown执行会让在任务队列中的任务继续执行完
* shutdownnow不会,而是返回没有执行的任务回来
*/
@Override
public void shutdown() {
//加锁防止多个线程同时执行
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//检查关闭线程池权限
checkShutdownAccess();
//修改线程池状态为关闭状态--该状态还可以继续处理阻塞队列中的任务
advanceRunState(SHUTDOWN);
//打断空闲线程
interruptIdleWorkers();
//钩子函数,模板方法,按需重写
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
//尝试终止线程池
tryTerminate();
}
/**
* 立即停止线程池,并返回阻塞队列中的任务
* @return
*/
@Override
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
//加锁,防止多个线程同时执行
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
//设置线程池状态为停止状态--该状态既不能接收新任务,也不执行阻塞队列中的任务
advanceRunState(STOP);
//打断所有的工作线程
interruptWorkers();
//取出阻塞队列中的任务
tasks = drainQueue();
} finally {
mainLock.unlock();
}
//终止线程池
tryTerminate();
return tasks;
}
@Override
public boolean isShutdown() {
return runStateAtLeast(ctl.get(), SHUTDOWN);
}
/** Used by ScheduledThreadPoolExecutor. */
boolean isStopped() {
return runStateAtLeast(ctl.get(), STOP);
}
public boolean isTerminating() {
int c = ctl.get();
return runStateAtLeast(c, SHUTDOWN) && runStateLessThan(c, TERMINATED);
}
/**
* 设置线程池状态为终止状态
* @return
*/
@Override
public boolean isTerminated() {
return runStateAtLeast(ctl.get(), TERMINATED);
}
/**
* 工作线程等待线程池终止
* @param timeout
* @param unit
* @return
* @throws InterruptedException
*/
@Override
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//线程池状态大于等于TERMINATED了,也就是线程池已经terminated了,则直接返回true
while (runStateLessThan(ctl.get(), TERMINATED)) {
// 如果达到超时时间,已经超时,则返回false
if (nanos <= 0L)
return false;
// 重置距离超时时间的剩余时长
nanos = termination.awaitNanos(nanos);
}
return true;
} finally {
mainLock.unlock();
}
}
@Override
@Deprecated(since="9")
protected void finalize() {}
public void setThreadFactory(ThreadFactory threadFactory) {
if (threadFactory == null)
throw new NullPointerException();
this.threadFactory = threadFactory;
}
public ThreadFactory getThreadFactory() {
return threadFactory;
}
public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
if (handler == null)
throw new NullPointerException();
this.handler = handler;
}
public RejectedExecutionHandler getRejectedExecutionHandler() {
return handler;
}
public void setCorePoolSize(int corePoolSize) {
if (corePoolSize < 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
if (workerCountOf(ctl.get()) > corePoolSize)
interruptIdleWorkers();
else if (delta > 0) {
// We don't really know how many new threads are "needed".
// As a heuristic, prestart enough new workers (up to new
// core size) to handle the current number of tasks in
// queue, but stop if queue becomes empty while doing so.
int k = Math.min(delta, workQueue.size());
while (k-- > 0 && addWorker(null, true)) {
if (workQueue.isEmpty())
break;
}
}
}
public int getCorePoolSize() {
return corePoolSize;
}
public boolean prestartCoreThread() {
return workerCountOf(ctl.get()) < corePoolSize &&
addWorker(null, true);
}
void ensurePrestart() {
int wc = workerCountOf(ctl.get());
if (wc < corePoolSize)
addWorker(null, true);
else if (wc == 0)
addWorker(null, false);
}
public int prestartAllCoreThreads() {
int n = 0;
while (addWorker(null, true))
++n;
return n;
}
public boolean allowsCoreThreadTimeOut() {
return allowCoreThreadTimeOut;
}
public void allowCoreThreadTimeOut(boolean value) {
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
if (value != allowCoreThreadTimeOut) {
allowCoreThreadTimeOut = value;
if (value)
interruptIdleWorkers();
}
}
public void setMaximumPoolSize(int maximumPoolSize) {
if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
this.maximumPoolSize = maximumPoolSize;
if (workerCountOf(ctl.get()) > maximumPoolSize)
interruptIdleWorkers();
}
public int getMaximumPoolSize() {
return maximumPoolSize;
}
public void setKeepAliveTime(long time, TimeUnit unit) {
if (time < 0)
throw new IllegalArgumentException();
if (time == 0 && allowsCoreThreadTimeOut())
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
long keepAliveTime = unit.toNanos(time);
long delta = keepAliveTime - this.keepAliveTime;
this.keepAliveTime = keepAliveTime;
if (delta < 0)
interruptIdleWorkers();
}
public long getKeepAliveTime(TimeUnit unit) {
return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
}
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}
public boolean remove(Runnable task) {
boolean removed = workQueue.remove(task);
tryTerminate(); // In case SHUTDOWN and now empty
return removed;
}
public void purge() {
final BlockingQueue<Runnable> q = workQueue;
try {
Iterator<Runnable> it = q.iterator();
while (it.hasNext()) {
Runnable r = it.next();
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
it.remove();
}
} catch (ConcurrentModificationException fallThrough) {
// Take slow path if we encounter interference during traversal.
// Make copy for traversal and call remove for cancelled entries.
// The slow path is more likely to be O(N*N).
for (Object r : q.toArray())
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
q.remove(r);
}
tryTerminate(); // In case SHUTDOWN and now empty
}
public int getPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Remove rare and surprising possibility of
// isTerminated() && getPoolSize() > 0
return runStateAtLeast(ctl.get(), TIDYING) ? 0
: workers.size();
} finally {
mainLock.unlock();
}
}
public int getActiveCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int n = 0;
for (ThreadPoolExecutor.Worker w : workers)
if (w.isLocked())
++n;
return n;
} finally {
mainLock.unlock();
}
}
public int getLargestPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
return largestPoolSize;
} finally {
mainLock.unlock();
}
}
public long getTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (ThreadPoolExecutor.Worker w : workers) {
n += w.completedTasks;
if (w.isLocked())
++n;
}
return n + workQueue.size();
} finally {
mainLock.unlock();
}
}
public long getCompletedTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (ThreadPoolExecutor.Worker w : workers)
n += w.completedTasks;
return n;
} finally {
mainLock.unlock();
}
}
@Override
public String toString() {
long ncompleted;
int nworkers, nactive;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
ncompleted = completedTaskCount;
nactive = 0;
nworkers = workers.size();
for (ThreadPoolExecutor.Worker w : workers) {
ncompleted += w.completedTasks;
if (w.isLocked())
++nactive;
}
} finally {
mainLock.unlock();
}
int c = ctl.get();
String runState =
isRunning(c) ? "Running" :
runStateAtLeast(c, TERMINATED) ? "Terminated" :
"Shutting down";
return super.toString() +
"[" + runState +
", pool size = " + nworkers +
", active threads = " + nactive +
", queued tasks = " + workQueue.size() +
", completed tasks = " + ncompleted +
"]";
}
protected void beforeExecute(Thread t, Runnable r) { }
/**
* <pre> {@code
* class ExtendedExecutor extends ThreadPoolExecutor {
* // ...
* protected void afterExecute(Runnable r, Throwable t) {
* super.afterExecute(r, t);
* if (t == null
* && r instanceof Future<?>
* && ((Future<?>)r).isDone()) {
* try {
* Object result = ((Future<?>) r).get();
* } catch (CancellationException ce) {
* t = ce;
* } catch (ExecutionException ee) {
* t = ee.getCause();
* } catch (InterruptedException ie) {
* // ignore/reset
* Thread.currentThread().interrupt();
* }
* }
* if (t != null)
* System.out.println(t);
* }
* }}</pre>
*
* @param r the runnable that has completed
* @param t the exception that caused termination, or null if
* execution completed normally
*/
protected void afterExecute(Runnable r, Throwable t) { }
protected void terminated() { }
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
}