Executor线程池源码详解

目录

一、线程池重点属性详解

二、线程池的状态

三、execute方法源码详解


一、线程池重点属性详解

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

ctl是对线程池的运行状态和线程池中有效线程的数量进行控制的一个手段,它包含两部分信息:线程池的运行状态(runState)和线程池内有效线程的数量(workerCount),这里的相关方法使用了Integer类型来保存,高3位保存runstate,低29位来保存workerCount。COUNT_BITS就是29,CAPACITY就是1左移29位减1(29个1),这个常量表示workerCount的上限值,大约时5亿。

//runStateOf:获取运行状态
private static int runStateOf(int c)     { return c & ~CAPACITY; }
//workerCountOf:获取活动线程数
private static int workerCountOf(int c)  { return c & CAPACITY; }
//ctlOf:获取运行状态和活动线程数(|为逻辑运算符,表示rs和wc都在计算)
private static int ctlOf(int rs, int wc) { return rs | wc; }

二、线程池的状态

private static final int RUNNING    = -1 << COUNT_BITS;  //高3位为111
private static final int SHUTDOWN   =  0 << COUNT_BITS;  //高3位为000
private static final int STOP       =  1 << COUNT_BITS;  //高3位为001
private static final int TIDYING    =  2 << COUNT_BITS;  //高3位为010
private static final int TERMINATED =  3 << COUNT_BITS;  //高3位为011

RUNNING:线程池在该状态时,可以接收新任务,以及对任务进行处理;

SHUTDOWN:线程池在该状态时,不接收新任务,但能够处理已经添加的任务;

STOP:线程池在该状态时,不接收新任务,不处理已添加的任务,且会中断正在处理的任务。

TIDYING:当所有任务被终止,ctl纪录的任务数量为0,线程池会变为该状态时会执行钩子函数terminated()。

TERMINATED:当线程池在该状态时,线程池已彻底终止。

三、execute方法源码详解

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        //ctl的相关信息和方法作用,可以参考上面线程池重点属性详解
        //ctl中纪录这runState和workerCount
        //获取线程状态
        int c = ctl.get();  
        //如果活动线程数小于核心线程数
        if (workerCountOf(c) < corePoolSize) { 
            //新建一个线程放入线程池中,并把任务添加到该线程中
            if (addWorker(command, true))
                return;
            //如果添加线程失败,则重新获取ctl值
            c = ctl.get();
        }
        /**isRunning(c)是判断当前线程的生命状态,因为上面的if创建了核心线程,
        如果上面的if判断不满足,到这里的if线程已经被关闭了,isRunning(c)获取线程
        生命状态正常,workQueue.offer()意思是把任务放到队列中*/
        if (isRunning(c) && workQueue.offer(command)) {
            //重新获取ctl值
            int recheck = ctl.get();
            /**再次判断当前线程生命状态,如果不运行,
            则把任务移除(因为上面已经有操作把任务放入队列中了)*/
            if (! isRunning(recheck) && remove(command))
                //拒绝策略处理
                reject(command);
            //获取线程池中的有效线程数,如果数量是0,则执行addWorker方法,也就是创建线程
            else if (workerCountOf(recheck) == 0)
                /**null:表示在线程池中创建一个线程,但不启动
                false:将线程池的有限线程数量的上限设置为最大线程数(maximumPoolSize),
                添加线程时根据最大线程数来判断,如果判断workerCount大于0,则直接返回,
                在workQueue中新增的任务会在之后的某个时刻被执行*/
                addWorker(null, false);
        }
        /**如果线程池时RUNNING状态,但是线程数小于核心线程数且队列已满,则再次调用
        addworker方法创建线程,第二个参数传入false的时候,将线程池中线程数量上限
        设置为最大线程数,如果失败执行拒绝策略*/
        else if (!addWorker(command, false))
            //拒绝策略处理
            reject(command);
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值