【高并发】深度解析ScheduledThreadPoolExecutor类的源代码( 四 )

总体来说reExecutePeriodic方法的逻辑比较简单,但是,这里需要注意和delayedExecute方法的不同点:调用reExecutePeriodic方法的时候已经执行过一次任务,所以,并不会触发线程池的拒绝策略;传入reExecutePeriodic方法的任务一定是周期性的任务 。
onShutdown方法onShutdown方法是ThreadPoolExecutor类中的钩子函数,它是在ThreadPoolExecutor类中的shutdown方法中调用的,而在ThreadPoolExecutor类中的onShutdown方法是一个空方法,如下所示 。
void onShutdown() {}ThreadPoolExecutor类中的onShutdown方法交由子类实现,所以ScheduledThreadPoolExecutor类覆写了onShutdown方法,实现了具体的逻辑,ScheduledThreadPoolExecutor类中的onShutdown方法的源码实现如下所示 。
@Overridevoid onShutdown() { //获取队列 BlockingQueue<Runnable> q = super.getQueue(); //在线程池已经调用shutdown方法后,是否继续执行现有延迟任务 boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy(); //在线程池已经调用shutdown方法后,是否继续执行现有定时任务 boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy(); //在线程池已经调用shutdown方法后,不继续执行现有延迟任务和定时任务 if (!keepDelayed && !keepPeriodic) {//遍历队列中的所有任务for (Object e : q.toArray())//取消任务的执行if (e instanceof RunnableScheduledFuture<?>)((RunnableScheduledFuture<?>) e).cancel(false);//清空队列q.clear(); } //在线程池已经调用shutdown方法后,继续执行现有延迟任务和定时任务 else {//遍历队列中的所有任务for (Object e : q.toArray()) {//当前任务是RunnableScheduledFuture类型if (e instanceof RunnableScheduledFuture) {//将任务强转为RunnableScheduledFuture类型RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e;//在线程池调用shutdown方法后不继续的延迟任务或周期任务//则从队列中删除并取消任务if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||t.isCancelled()) {if (q.remove(t))t.cancel(false);}}} } //最终调用tryTerminate()方法 tryTerminate();}ScheduledThreadPoolExecutor类中的onShutdown方法的主要逻辑就是先判断线程池调用shutdown方法后,是否继续执行现有的延迟任务和定时任务,如果不再执行,则取消任务并清空队列;如果继续执行,将队列中的任务强转为RunnableScheduledFuture对象之后,从队列中删除并取消任务 。大家需要好好理解这两种处理方式 。最后调用ThreadPoolExecutor类的tryTerminate方法 。有关ThreadPoolExecutor类的tryTerminate方法的源码解析,大家可以参考【高并发专题】中的《高并发之——通过源码深度分析线程池中Worker线程的执行流程》一文,这里不再赘述 。
至此,ScheduledThreadPoolExecutor类中的核心方法的源代码,我们就分析完了 。

经验总结扩展阅读