java线程池学习(五) —— ThreadPoolExecutor源码分析

通过前面的章节,我们学习了可以通过ThreadPoolExecutor来创建一个线程池。

那么接下来我们分析一下ThreadPoolExecutor的源码,看看它具体是如何工作的。

我们看一下使用execute(Runnable task)执行一个任务的时候,到底发生了什么(代码进过简化):

先简单描述一下当我们提交一个任务到线程池中后发生了什么:


具体源码如下:

    public void execute(Runnable task) {
        //取出当前线程池活跃的线程数。
        //ctl是一个原子类型的对象(final AtomicInteger ctl),用来保存当前线程池的线程数以及线程池的状态。
        int c = ctl.get();
        //如果当前的活跃线程数小于核心线程数,即使现在有空闲线程,也创建一个新的线程,去执行这个任务
        if (workerCountOf(c) < corePoolSize) {
            //创建一个新的线程,去执行这个任务。
            if (addWorker(task, true))
                return;
            //如果执行到这一句说明任务没有分配成功。
            //所以获得当前线程池状态值,为后面的检查做准备。
            c = ctl.get();
        }
        //如果大于核心线程数,检查一下线程池是否还处于运行状态,并尝试把任务放入到blockingQueue任务队列中。
        if (isRunning(c) && workQueue.offer(task)) {
            //这里再次检查一下线程池的状态
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(task))
                //如果线程池不处于运行状态的话,就把我们刚才添加进任务队列中的任务移出,并拒绝这个任务。
                reject(task);
            //检查如果当前线程池中的线程数,如果为0了,就为线程池创建新线程(因为有可能之前存活的线程在上一次检查过后死亡了)
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //执行到这一句,说明队列满了。这时,如果当前线程池中的线程数还没有超过最大线程数,就创建一个新的线程去执行这个任务,如果失败就拒绝这个任务。
        else if (!addWorker(task, false))
            reject(task);
    }


以上就是ThreadPoolExecutor的基本执行流程。

发布了40 篇原创文章 · 获赞 32 · 访问量 11万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章