线程池关闭
tryTerminate实现
tryTerminate()不会强制终止线程池,只是做一下检测,只有在workerCount为0,workQueue为空时,才会关闭线程池
final void tryTerminate() {
for (;;) {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
// 1. 当workQueue为空(没有任务需要执行),且workCount为0(线程回收完)时,才会走到这里
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 2. 设置线程池状态为TIDYING
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
// 3. 设置线程池状态为TERMINATED
ctl.set(ctlOf(TERMINATED, 0));
// 4. 激活termination的await系列方法而被阻塞的所有线程
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
shutdown操作
调用shutdown方法后,线程池不再接受新的任务,但是工作队列中的任务还是可以执行(在getTask()方法中,当线程池为SHUTDOWN时,若任务队列不为空,仍然会从任务队列中获取任务),该方法会立刻返回,并不等待队列完成再返回。
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 1. 权限检查
checkShutdownAccess();
// 2. 设置当前线程池为SHUTDOWN状态
advanceRunState(SHUTDOWN);
// 3. 设置中断标记
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
// 4. 尝试将状态设置为TERMINATED
tryTerminate();
}
shutdown()方法中使用全局锁,保证只有一个线程可以执行调用shutdown方法设置中断位,interruptIdleWorkers()中尝试获取Work线程内的锁,获取成功设置中断标记。线程在运行时,会加Work线程内的锁,因此正在运行的任务不会设置中断标记位,这里中断的是阻塞在getTask()方法中从队列中获取任务的线程,即空闲线程(等待任务的线程)。
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;
if (!t.isInterrupted() && w.tryLock()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
shutdownNow操作
调用shutdownNow方法,线程池不再接收新的任务,并且会丢弃工作队列里面的任务(在getTask()方法中,当线程池为STOP时,方法会直接返回null,不执行任务队列中的任务),正在执行的任务会被中断,该方法会直接返回,返回值是队列中被丢弃的任务。
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(STOP);
// 中断所有线程
interruptWorkers();
// 将队列移动到tasks中
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();
}
}
// 中断线程
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
awaitTermination操作
当调用awaitTermination()方法后,会先判断线程池是否为TERMINATED,若是则返回true表示线程池已关闭;否则超时等待,当等待结束后,线程池仍未关闭,则返回false表示线程池未关闭。
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (;;) {
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
if (nanos <= 0)
return false;
// 1. tryTerminate()方法会在线程池关闭后激活该等待的线程
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}
优雅关闭线程池
executor.shutdown();
//executor.shutdownNow();
try{
boolean isRunning;
do {
// 循环判断线程池是否已关闭
isRunning = !executor.awaitTermination(1, TimeUnit.SECONDS);
}while (isRunning);
}catch (InterruptedException e){
//...
}