源码阅读 - 线程池:线程池原理(五)一个execute(Runnable)调用经历了什么?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/lidelin10/article/details/100031565

该文章的主要目的是为了介绍execute方法的主要逻辑,还讨论了线程池的增长

线程的工作线程和任务的提交执行受到线程池状态的影响,情况颇为复杂,不过总结起来,梳理清楚,不禁大赞doug lea。(流程图好难画啊)

execute的源码如下:

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    int c = ctl.get();
    //判断核心线程数量
    if (workerCountOf(c) < corePoolSize) {
        // 使用corePoolSize扩充线程池
        if (addWorker(command, true))    
            return;
        //添加失败
        c = ctl.get();
    }
    
    //1、线程创建失败
    //2、线程池SHUTDOWN状态
    // workQueue.offer(command) 队列饱和
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
        // 线程池状态不是RUNNING 且 移除成功
        if (! isRunning(recheck) && remove(command))
            reject(command);
        // 线程池为工作状态 或 移除失败,需要有工作线程执行移除失败的任务的任务
        else if (workerCountOf(recheck) == 0)
            //因为firstTask为空是为了添加一个没有任务的线程再从workQueue获取task,而workQueue为空,说明添加无任务线程已经没有意义,这应该是最后移除任务的保险
            addWorker(null, false);
    }    
    // 使用maxPoolSize扩充线程池
    else if (!addWorker(command, false))
        reject(command);
}

如果一个线程池为空,大致会通过如下流程增长:
1、添加核心线程;
2、如果核心线程已满,工作任务入队;
3、如果工作任务队列已满,说明核心线程的数量无法及时处理当前过饱和工作任务队列,添加工作线程;

猜你喜欢

转载自blog.csdn.net/lidelin10/article/details/100031565