补充了和Thread的interrupt操作相关的知识,回头再来看ThreadPoolExecutor中interrupt,关闭线程池等相关操作。
1.shutdown
/**
* Initiates an orderly shutdown in which previously submitted
* tasks are executed, but no new tasks will be accepted.
* Invocation has no additional effect if already shut down.
*
* <p>This method does not wait for previously submitted tasks to
* complete execution. Use {@link #awaitTermination awaitTermination}
* to do that.
*
* @throws SecurityException {@inheritDoc}
*/
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
tryTerminate();
}
先看注释:
开始一个顺序的shutdown操作,shutdown之前被执行的已提交任务,新的任务不会再被接收了。如果线程池已经被shutdown了,该方法的调用没有其他任何效果了。
该方法不会等待之前已经提交的任务执行完毕,awaitTermination方法才有这个效果。
具体看内部逻辑,checkShutdownAccess这个方法是确保允许调用发interrupt每个Worker线程的,具体就不看了。
1.advanceRunState方法
/**
* Transitions runState to given target, or leaves it alone if
* already at least the given target.
*
* @param targetState the desired state, either SHUTDOWN or STOP
* (but not TIDYING or TERMINATED -- use tryTerminate for that)
*/
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
该方法会原子设置线程池的rs(runState)。
设置的逻辑是,如果当前的线程池状态已经是要设置的状态,或者已经超过了要设置状态(runStateAtLeast方法返回值是true),就保持不做任何操作了,直接break。
如果线程池当前状态比要设置的状态小,比如当前是RUNNING,要设置是的SHUTDOWN,那么runStateAtLeast方法返回false,继续走第二个判断,原子设置rs,如果失败的话继续这个流程。
2.interruptIdleWorkers方法
/**
* Common form of interruptIdleWorkers, to avoid having to
* remember what the boolean argument means.
*/
private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}
内部调用了interruptIdleWorkers方法,参数默认设置为false了。具体参数的含义下一个段落说interruptIdleWorkers方法的时候再说。
这里简单说一下传false的效果,就是检查当前所有worker线程,在获取Worker锁的情况下,把所有没有interrupt的线程都执行interrupt操作。
2.interruptIdleWorkers
/**
* Interrupts threads that might be waiting for tasks (as
* indicated by not being locked) so they can check for
* termination or configuration changes. Ignores
* SecurityExceptions (in which case some threads may remain
* uninterrupted).
*
* @param onlyOne If true, interrupt at most one worker. This is
* called only from tryTerminate when termination is otherwise
* enabled but there are still other workers. In this case, at
* most one waiting worker is interrupted to propag