摘要:结合ThreadPoolExecutor类的源码深度分析线程池执行任务的整体流程。
本文分享自华为云社区《【高并发】通过ThreadPoolExecutor类的源码深度解析线程池执行任务的核心流程》,作者: 冰 河。
ThreadPoolExecutor类中存在一个workers工作线程集合,用户可以向线程池中添加需要执行的任务,workers集合中的工作线程可以直接执行任务,或者从任务队列中获取任务后执行。ThreadPoolExecutor类中提供了整个线程池从创建到执行任务,再到消亡的整个流程方法。本文,就结合ThreadPoolExecutor类的源码深度分析线程池执行任务的整体流程。
在ThreadPoolExecutor类中,线程池的逻辑主要体现在execute(Runnable)方法,addWorker(Runnable, boolean)方法,addWorkerFailed(Worker)方法和拒绝策略上,接下来,我们就深入分析这几个核心方法。
execute(Runnable)方法execute(Runnable)方法的作用是提交Runnable类型的任务到线程池中。我们先看下execute(Runnable)方法的源码,如下所示。
public void execute(Runnable command) { //如果提交的任务为空,则抛出空指针异常 if (command == null) throw new NullPointerException(); //获取线程池的状态和线程池中线程的数量 int c = ctl.get(); //线程池中的线程数量小于corePoolSize的值 if (workerCountOf(c) < corePoolSize) { //重新开启线程执行任务 if (addWorker(command, true)) return; c = ctl.get(); } //如果线程池处于RUNNING状态,则将任务添加到阻塞队列中 if (isRunning(c) && workQueue.offer(command)) { //再次获取线程池的状态和线程池中线程的数量,用于二次检查 int recheck = ctl.get(); //如果线程池没有未处于RUNNING状态,从队列中删除任务 if (! isRunning(recheck) && remove(command)) //执行拒绝策略 reject(command); //如果线程池为空,则向线程池中添加一个线程 else if (workerCountOf(recheck) == 0) addWorker(null, false); } //任务队列已满,则新增worker线程,如果新增线程失败,则执行拒绝策略 else if (!addWorker(command, false)) reject(command); }