当前位置 博文首页 > 龚厂长的博客:java8 ThreadPoolExecutor之shutdown()与shutdown
研究ThreadPoolExecutor源码时,发现两个方法:shutdown()和shutdownNow(),从名字上看都是关闭,只是后者多了一个Now,那么它们两个有什么区别呢?
首先先来看代码:
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(SHUTDOWN);//通过自旋锁不断的修改线程池状态,直到修改成功为止
interruptIdleWorkers();
onShutdown(); // 空实现,子类可以覆盖
} finally {
mainLock.unlock();
}
tryTerminate();
}
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;
}
先来说共同点:
下面来看一下两者的不同点:
//入参是目标状态
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
//新建List对象,用于存储阻塞队列中的任务
ArrayList<Runnable> taskList = new ArrayList<Runnable>();
q.drainTo(taskList);//清空阻塞队列,将任务放到新建的List中
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}
final void tryTerminate() {
for (;;) {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) {
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
}
}
cs