之前在第一篇文章介绍了线程池的一些整体知识:
Java线程池ThreadPoolExecutor详解(一) --基于JDK1.8
现在我们来分析一下源码:
目录
1、类属性变量
(1)、全局变量
a、线程池基本变量属性
b、线程池状态字段属性
c、线程池其它重要意义字段
(2)、构造方法
a、常用构造方法源码:
b、构造方法参数解析:
(3)、Worker对象
2、执行任务方法
(1)、无返回值执行任务方法execute():
(2)、execute()中addWorker方法
(3)、runWorker执行线程方法:
(4)、runWorker中获取任务getTask方法:
(5)、processWorkerExit方法
(6)、submit()提交任务方法
3、关闭线程池方法
(1)、shutdown()
(2)、shutdownNow()
(3)、tryTerminate()方法
// ctl 其实可以理解为单词 control 的简写, 翻译就是“控制”;
//修改此变量的操作,是原子性的;
//ctl 变量是Integer类型的,Integer.size在大多平台上是32位,
//该变量包含了两部分信息: 线程池的运行状态 (runState,前3位) ,
//和线程池内有效线程的数量 (workerCount,后29位);
//在下面的属性方法中,ctl 简写c,runState简写rs,workerCount简写wc;
//初始化为RUNNING状态,线程个数为0
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//32-3=29,在大多平台上Integer.size = 32 位,之所以不直接用数字29,
//是为了规范性
private static final int COUNT_BITS = Integer.SIZE - 3;
//线程池最大数,1左移29位,再减1,除前3位状态位,值全为1,
//即000 11111 11111111 11111111 11111111
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
关于下面几个线程池的状态,我们在源码中可以看到这样的注释:
* The runState provides the main lifecycle control, taking on values:
*
* RUNNING: Accept new tasks and process queued tasks
* SHUTDOWN: Don't accept new tasks, but process queued tasks
* STOP: Don't accept new tasks, don't process queued tasks,
* and interrupt in-progress tasks
* TIDYING: All tasks have terminated, workerCount is zero,
* the thread transitioning to state TIDYING
* will run the terminated() hook method
* TERMINATED: terminated() has completed
*
* The numerical order among these values matters, to allow
* ordered comparisons. The runState monotonically increases over
* time, but need not hit each state. The transitions are:
*
* RUNNING -> SHUTDOWN
* On invocation of shutdown(), perhaps implicitly in finalize()
(a)显式调用 shutdown() 方法,或者隐式调用了 finalize(),它里面调用了 shutdown() 方法;常见状态转换之一;
* (RUNNING or SHUTDOWN) -> STOP
* On invocation of shutdownNow()
(b)显式调用 shutdownNow() 方法时候;常见状态转换之一;
* SHUTDOWN -> TIDYING
* When both queue and pool are empty
(c)当线程池和任务队列为空的时候
* STOP -> TIDYING
* When pool is empty
(d)当线程池为空的时候
* TIDYING -> TERMINATED
* When the terminated() hook method has completed
(e)当 terminated() hook 方法执行完成时候
//之前我们讲过,整数在计算书二进制中存放的方式都是补码,
// -1的补码是11111111 11111111 11111111 11111111,
// 左移29位 即111 00000 00000000 00000000 00000000
//running状态,接受新的任务,并且处理在阻塞队列中排队的任务
private static final int RUNNING = -1 << COUNT_BITS;
// 左移29位 即000 00000 00000000 00000000 00000000
//不再接受新任务,继续处理在阻塞队列排队中的任务
private static final int SHUTDOWN = 0 << COUNT_BITS;
// 左移29位 即001 00000 00000000 00000000 00000000
//不在接受新任务,不处理在阻塞队列排队中的任务,
// 并且会中断正在运行中的任务
private static final int STOP = 1 << COUNT_BITS;
// 左移29位 即010 00000 00000000 00000000 00000000
//整理中状态,所有任务执行完,阻塞队列执行完,工作线程数为0,过渡到此//状态的工作线程会调用方法terminated()
private static final int TIDYING = 2 << COUNT_BITS;
// 左移29位 即011 00000 00000000 00000000 00000000
//终态,上述讲的terminated()方法执行完成后的状态
private static final int TERMINATED = 3 << COUNT_BITS;
// 将整数 c 低 29位与0计算,得到ctl前3位的值,即线程池的状态
private static int runStateOf(int c) { return c & ~CAPACITY;
// 将整数 c 低 29位与1计算,得到ctl后29位的值,即池中线程数量
private static int workerCountOf(int c) { return c & CAPACITY; }
// 计算ctl新值,即新的线程状态 与 线程个数
private static int ctlOf(int rs, int wc) { return rs | wc; }
//线程池主锁
private final ReentrantLock mainLock = new ReentrantLock();
//存放worker的HashSet
private final HashSet workers = new HashSet();
//主锁等待条件队列,用于awaitTermination方法,在调用shutdown()或者//shutdownNow()方法后,其实线程池并没有真正关闭,这个方法可以设定一
//个超时时间,来检查在时间内线程池是否真正已经达到TERMINATED状态;
private final Condition termination = mainLock.newCondition();
//线程池曾经创建过的最大线程数量。通过getLargestPoolSize()方法可以知道//线程池是否满过,也就是达到了maximumPoolSize
private int largestPoolSize;
//已完成任务数
private long completedTaskCount;
/**
* If false (default), core threads stay alive even when idle.
* If true, core threads use keepAliveTime to time out waiting
* for work.
默认为false,核心线程池不会被回收,哪怕在闲置以后;
如果设置为true,就在keepAliveTime到达超时后回收;
*/
private volatile boolean 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();
}
}
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:
* {@code corePoolSize < 0}
* {@code keepAliveTime < 0}
* {@code maximumPoolSize <= 0}
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue 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.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
(a)、int corePoolSize (核心线程数大小):当提交一个任务到线程池时,即便目前池中有空闲线程能够执行任务,线程池也会创建一个新线程来执行任务,直到池中线程数达到corePoolSize 数量;在这里要注意一点,线程池刚创建的时候,其中并没有创建任何线程数,而是等有任务提交后再去创建线程,除非调用了 prestartAllCoreThreads() 或者 prestartCoreThread() 方法 ,这样才会预先创建 corePoolSize 数量的线程。
(b)、int maximumPoolSize (线程池最大线程数):线程池允许创建的最大线程数,如果线程池队列已满,并且已创建线程数小于最大线程数maximumPoolSize,则线程池会再创建新的线程执行任务,所以在通常情况下,
maximumPoolSize >= corePoolSize , 值得注意的是,如果使用了无界队列,最大线程数此参数就没意义了。
(c)、long keepAliveTime (线程闲置存活时间):此参数默认在当前线程数大于 corePoolSize 的情况下才会起作用, 当这些多余的线程,空闲时间达到 keepAliveTime 的时候就会终止,直至线程数目减到 corePoolSize 。不过如果调用了 allowCoreThreadTimeOut 方法,则当线程数目小于 corePoolSize 的时候也会起作用,keepAliveTime到达后闲置线程也会终止;
(d)、TimeUnit unit (keelAliveTime的时间单位):keelAliveTime的时间单位,一共有7种,纳秒、微秒、毫秒等等。
(e)、BlockingQueue
· ArrayBlockingQueue:这是一个基于数组结构的有界阻塞队列,此队列按照FIFO的先进先出规则,进和出用的是同一个可重入锁。
· LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按照FIFO排序元素,进和出分别采用两把锁,所以吞吐量通常要高于ArrayBlockingQueue。静态工厂方法 Executors.newFixedThreadPool() 使用了这个队列。
· SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于Linked-BlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
· PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
(f)、ThreadFactory threadFactory(创建线程池工厂):用于设置创建线程的工厂,默认是使用Executors.defaultThreadFactory(),可以通过线程工厂给每个创建出来的线程设置更有意义的名字。使用开源框架guava提供的ThreadFactoryBuilder可以快速给池里的线程设置有意义的名字,代码如下:
new ThreadFactoryBuilder().setNameFormat("XX-task-%d").build();
(g)、RejectedExecutionHandler handler(饱和策略);当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。从JDK 1.5开始, Java线程池框架提供了以下4种策略:
· AbortPolicy:直接丢弃并且抛出 RejectedExecutionException 异常(默认)
· CallerRunsPolicy:这个策略重试添加当前的任务,他会自动重复调用 execute() 方法,线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。这个策略显然不想放弃执行任务。
但是由于池中已经没有任何资源了,那么就直接使用调用该execute的线程本身来执行;
· DiscardOldestPolicy:如果执行程序尚未关闭,则位于阻塞队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程);
· DiscardPolicy:直接丢弃后面提交的任务并且不抛出异常。
使用Executors最常用的莫过于是使用:Executors.newFixedThreadPool(int)这个方法,因为它既可以限制数量,而且线程用完后不会一直被cache住;
其它构造方法,大同小异,支持传入ThreadFactory threadFactory,
RejectedExecutionHandler handler参数,自己设置线程工厂、拒绝策略;
线程池中的线程,都被封装成了Worker对象,线程池维护的一组Worker对象,而Worker对象又继承AbstractQueuedSynchronizer类,使用AQS来实现独占锁的功能,
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/**
* This class will never be serialized, but we provide a
* serialVersionUID to suppress a javac warning.
*/
private static final long serialVersionUID = 6138294804551838833L;
/** 线程对象,真正在执行任务的活动线程 */
final Thread thread;
/**这里的 Runnable 是任务:在创建线程后需要执行的第一个任务,如果这个传入对象为空,在线程启动之后,不是执行空的任务,而是会到阻塞任务队列中自行取任务执行*/
Runnable firstTask;
/**该线程完成的任务数 */
volatile long completedTasks;
/**
* Creates with given first task and thread from ThreadFactory.
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
//将state设置为-1,是为了防止在执行任务前对线程进行中断
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/**调用外部主类的 runWorker 方法来运行线程 */
public void run() {
runWorker(this);
}
}
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//获取ctl变量,状态和线程数
int c = ctl.get();
//如果当前线程数小于核心线程数,创建新线程执行该任务
if (workerCountOf(c) < corePoolSize) {
//第二个参数为true的时候,表示用corePoolSize
//作为线程池工作线程数大小的上限,否则使用
//maximumPoolSize作为线程池工作线程数上限;
if (addWorker(command, true))
return;
c = ctl.get();
}
//如果线程池处于运行状态,并且插入阻塞队列排队成功
if (isRunning(c) && workQueue.offer(command)) {
//再检查一次ctl变量
int recheck = ctl.get();
//如果线程池处于非运行状态,
//如果现在正在关闭线程池,并且从阻塞队列成功移除当前线程;
//就执行拒绝策略;
if (! isRunning(recheck) && remove(command))
reject(command);
//如果线程池还是运行状态的,并且当前池中可用线程为0,
//那么需要开启新的线程,并且addWorker方法第二个参数
//为false,表示最大线程数可到maximumPoolSize;
//防止任务在阻塞队列中后,但是可运行线程都关闭了
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 如果执行到这个if分支,有两种情况:
//a、线程池非RUNNING状态;
//b、或者线程池是RUNNING状态,但workerCount >= corePoolSize
//并且workQueue.offer返回false(说明阻塞队列已满),这时调用
//addWorker方法,但第二个参数传入为false,将线程池的有限线程数量
//的上限设置为maximumPoolSize;
else if (!addWorker(command, false))
//添加线程任务失败,对当前线程执行拒绝策略;
reject(command);
}
addWorker()方法,主要作用是在线程池中创建一个新的线程并执行添加进来的任务,并且firstTask是新增线程需要执行的第一个任务:
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
//循环直到满足true或false,作为addWorker方法返回值
for (;;) {
//获取线程池ctl变量来得到运行状态
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
//1、如果线程池不是SHUTDOWN或者后面的状态
//(STOP, TIDYING, 或 TERMINATED):
//则不满足if条件,那么逻辑向下执行,创建新线程接收执行任务;
// false && ? == false;
//2、如果线程池状态是SHUTDOWN状态:
//(a)、并且下列语句条件只有全满足true时,
// r s == SHUTDOWN && firstTask == null &&
// ! workQueue.isEmpty();
//即线程池目前SHUTDOWN状态,新传入的任务对象为空,
//并且阻塞任务队列不为空;
//那么方法不返回,继续向下执行,因为目前队列中还有任务,
//所以线程池继续运行,允许创建线程执行任务;
// true && ! (true && true&& !false) == false
//(b)、SHUTDOWN状态,如果传入firstTask任务对象不为空,
//不再新增任务线程,方法返回false;
// true && ! (true && false&& ? ) == true
//(c)、SHUTDOWN状态,如果传入firstTask任务对象为空,
//并且目前任务阻塞队列为空,队列都空了,所以无需新增任务线程;
//方法返回false;
// true && ! (true && true&& ! ture ) == true
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
//获取线程数;
int wc = workerCountOf(c);
//根据core的boolean值,来决定取,
//当前线程数wc是否超过CAPACITY和corePoolSize中最小值,
//还是超过CAPACITY和maximumPoolSize中最小值;
//如果超过了,那么返回不再添加新线程执行任务;
//所以如果core传入false的话,那么运行线程池线程执行数
//增加到maximumPoolSize;
//core传入true的话,当前线程池线程数大于corePoolSize后,
//不允许再增加线程数,addWorker方法返回false;
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
//尝试CAS增加workerCount线程数,
//如果添加成功则跳出最外层for循环,
//并且将workerCount加1
if (compareAndIncrementWorkerCount(c))
break retry;
//竞争添加失败,重新获取状态值,
//跳出内for循环,从外for下一次循环继续开始;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
//执行到此处,说明工作线程数workerCount已经+1
// worker是否已启动
boolean workerStarted = false;
// worker是否已添加成功
boolean workerAdded = false;
Worker w = null;
try {
// 把firstTask创建成worker对象,
//worker构造方法会从ThreadFactory创建一个线程
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());
//如果是SHUTDOWN之前的状态(只有RUNNING),
//或者现在是SHUTDOWN并且传入的firstTask为空;
//校验当前线程是否启动,因为workder中的线程不允许
//是启动的,已启动抛出IllegalThreadStateException
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
//添加到worker队列
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
//添加worker队列成功后,启动这个线程
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
//添加worker失败,addWorkerFailed方法善后工作
addWorkerFailed(w);
}
return workerStarted;
}
//addWorkerFailed方法善后工作
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
//从worker队列中移除
workers.remove(w);
//将workerCount减1
decrementWorkerCount();
//尝试将线程池置为TERMINATED状态,当对线程池执行了
//非正常逻辑的操作时,都需执行tryTerminate判断是否结束线程池
tryTerminate();
} finally {
//在finally块中释放锁
mainLock.unlock();
}
}
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
//循环调用getTask方法获取任务
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,线程就应中断
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 new Error(x);
} finally {
//同样留给子类的方法
afterExecute(task, thrown);
}
} finally {
task = null;
//完成任务数+1
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//当上面的while循环中getTask方法执行完毕以后,线程队列为空了,
//统计整个线程池完成的任务个数,并从工作队列删除当前woker,
//执行善后清理工作
processWorkerExit(w, completedAbruptly);
}
}
getTask方法返回null时,在之前runWorker方法中会跳出while循环,runWorker会执行finally块中的processWorkerExit方法:
在执行execute方法时,如果当前线程池的线程数量超过了corePoolSize,并且workQueue已满时,则可以增加工作线程数到maximumPoolSize,但这时如果超时没有获取到任务,也就是timedOut为true的情况,说明workQueue已经为空了,那么当前线程池中不需要那么多线程来执行任务了,可以把多于corePoolSize数量的线程销毁掉,,如果之前设置过allowCoreThreadTimeOut为true,那么运行线程池数量降至corePoolSize以下。
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
// 获取线程状态
int rs = runStateOf(c);
// 如果线程池关闭或者正在关闭,那么执行workerCount减1
//方法返回null
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
// cas方法,减少线程数workerCount
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
//如果之前allowCoreThreadTimeOut设置为true,
//或者当前池中运行线程大于corePoolSize,
//timed就为true;
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
//timedOut如果为true,说明上次循环有超时发生,
// timed && timedOut 如果为true,表示需要超时超数控制,
// 判断workerCount是否大于最大线程池数或者需超时空总控制,
//是的话workerCount减1,减1成功后返回null,
//不成功则continue继续执行
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
//到 workQueue 中获取任务
//如果上面的timed为true,则用poll超时方法从
//阻塞队列中取线程对象;否则用take方法取线程对象
//阻塞队列中,take方法是阻塞的,如果队列元素为0则一直阻塞等待
//而poll方法是非阻塞的,这里给定超时时间,获取不到直接返回;
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
//如果r不为空,说明已经从阻塞队列获取到线程对象,
//否则没获取到线程对象,设置timedOut为true;
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
runWorker()方法执行完任务后,或者执行任务过程中出现异常中断执行的时,相对应的操作方法;
并且这里会移除线程池中的线程,因为异常情况添加到池中的线程没有执行的,这里移除以后重新添加线程执行;
private void processWorkerExit(Worker w, boolean completedAbruptly) {
//如果正常执行完成,runWorker方法中completedAbruptly传的false
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
//非正常执行完,线程池工作线程数减1
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//完成任务数
completedTaskCount += w.completedTasks;
//从线程池中移除一个工作线程,那么这个线程就销毁了;
//这里只负责移除,在runWorker方法执行完之后,也就是Worker
//中的run方法执行完,由JVM自动回收;
workers.remove(w);
} finally {
mainLock.unlock();
}
//非正常逻辑的操作时,都需执行tryTerminate判断是否结束线程池
tryTerminate();
int c = ctl.get();
//如果是STOP之前的状态,即RUNNING或SHUTDOWN
if (runStateLessThan(c, STOP)) {
//如果是正常结束
if (!completedAbruptly) {
//allowCoreThreadTimeOut为true,
//允许核心线程数收回,设置min为0,否则为核心线程数大小
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
//如果线程队列中还有线程,那么至少保留一个线程
if (min == 0 && ! workQueue.isEmpty())
min = 1;
//当前线程数比min(0或corePoolSize)大,无需新增线程
if (workerCountOf(c) >= min)
return; // replacement not needed
}
//否则应该是异常情况,重新添加一个线程执行任务;
addWorker(null, false);
}
}
public Future submit(Callable task) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task);
//实际上执行的是execute方法,但是这里会有Future返回值,
//后续可以通过Future调用get方法异步阻塞获取线程返回值;
execute(ftask);
return ftask;
}
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//检查关闭权限,如果设置了安全管理,则看当前调用 shutdown
//方法的线程是否有关闭线程的权限
checkShutdownAccess();
//检查当前状态如果是SHUTDOWN之后的状态则返回,
//如果不是SHUTDOWN状态,设置当前状态为 SHUTDOWN
advanceRunState(SHUTDOWN);
//这个方法有必要分析一下,往下看,从中文名称翻译来讲:
//打断空闲的工作者
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
//结束线程池
tryTerminate();
}
private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
Thread t = w.thread;
//这里为什么要去获取w线程对象的锁,之前我们在看
//addWorker()和runWorker()方法的时候,看到了对worker加
//锁,说明正在入队的线程和正在执行的线程,不会中断他们;
//这就是与下面shutdownNow()关闭线程池方法的区别所在;
if (!t.isInterrupted() && w.tryLock()) {
try {
//满足上面的条件:线程非中断状态,并且获取锁
//则中断当前线程;
t.interrupt();
} catch (SecurityException ignore) {
} finally {
//释放当前线程锁
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
//释放线程池主锁
mainLock.unlock();
}
}
public List shutdownNow() {
List tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//检查是否有关闭权限
checkShutdownAccess();
//设置线程池状态为STOP
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
} finally {
mainLock.unlock();
}
//结束线程池
tryTerminate();
return tasks;
}
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//这里就比较简单粗暴,直接去打断线程,并不检查当前线程是否正在
//运行或者已经添加到队列中;
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
}
//我们看到shutdownNow()方法的返回类型是List,
//这个方法就是把目前阻塞队列中的元素都移除,并且封装到List集合里,
//返回给shutdownNow的调用者
private List drainQueue() {
BlockingQueue q = workQueue;
ArrayList taskList = new ArrayList();
q.drainTo(taskList);
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}
之前的关闭线程池方法和一些方法非正常执行后,都会调用tryTerminate:
final void tryTerminate() {
for (;;) {
int c = ctl.get();
//RUNNING或TIDYING或(SHUTDOWN并且队列不为空)
//这时候不会关闭线程池;
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
//如果池中线程数量不为0,则只中断一个空闲的线程
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//如果设置线程池状态为TIDYING成功,
//则调用terminated方法(此方法内容为空,想做啥留给实现子类)
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
//最后设置线程池状态为TERMINATED
ctl.set(ctlOf(TERMINATED, 0));
//唤醒termination条件,在这个变量注释处提到过
//的awaitTermination方法有用到
//termination.awaitNanos(nanos)
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
-------