线程池源码(一)

一, ThreadPoolExecutor执行流程

二, ThreadPoolExecutor状态

线程池中核心属性 ctl

//ctl本质就是一个int类型的数值
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// COUNT_BITS = 32 - 3 = 29
// ctl表述了两个状态
//     1. 标识线程池当前的状态(高三位)
//     2. 标识线程池当前的工作线程个数(低29位)
private static final int COUNT_BITS = Integer.SIZE - 3;
//    表述了工作线程的最大数量
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;

// runState is stored in the high-order bits
// 线程池的5种状态
// 111
private static final int RUNNING    = -1 << COUNT_BITS;
// 000
private static final int SHUTDOWN   =  0 << COUNT_BITS;
// 001
private static final int STOP       =  1 << COUNT_BITS;
// 010
private static final int TIDYING    =  2 << COUNT_BITS;
// 011
private static final int TERMINATED =  3 << COUNT_BITS;
// c就是ctl,计算出当前线程池的状态,即高三位和后29位为0
private static int runStateOf(int c)     { return c & ~COUNT_MASK; }
// 计算当前线程池中的工作线程个数
private static int workerCountOf(int c)  { return c & COUNT_MASK; }

  1. 线程池创建后处理RUNNING 状态
  2. 调用shutdown()方法后处理SHUTDOWN状态,线程池不能接受新的任务,清除一些空闲worker,会等等阻塞队列的任务完成。
  3. 调用shutdownNow()方法后,处于STOP状态,线程池不能接受新的任务,中断所有线程,阻塞队列中没有被执行的任务全部丢弃。此时,poolsize=0,阻塞队列的size也是0。
  4. 当所有的任务已经终止,ctl记录的“任务数量”为0,线程池会变为TIDYING状态。接着会执行terminated()函数。
  5. 线程池处在TIDYING状态时,执行完terminated()方法之后,就会由TIDYING -> TERMINATED,线程池被设置为 TERMINATED状态。

三, Execute方法

public void execute(Runnable command) {
    //非空判断
    if (command == null)
        throw new NullPointerException();
    // 获取ctl属性
    int c = ctl.get();
    // 计算工作线程个数,是否小于核心线程数
    if (workerCountOf(c) < corePoolSize) {
        // 如果小于,添加核心线程去执行(true表示是核心线程)
        if (addWorker(command, true))
            // 添加核心线程成功,返回true,直接return结束
            return;
        // 如果在并发情况下,添加核心线程失败的线程,需要重新获取一次ctl属性
        c = ctl.get();
    }
    // 也就是创建核心线程失败,判断当前线程池状态是否是RUNNING
    // 如果不小于核心线程数,则将任务添加到workQueue工作队列
    if (isRunning(c) && workQueue.offer(command)) {
        // 添加到队列成功
        int recheck = ctl.get();
        // 判断线程池是否是RUNNING状态,如果isRunning返回false,则表明线程池当前状态不接受任务,
        // 则remove这个任务,然后执行拒绝策略
        if (! isRunning(recheck) && remove(command))
        //执行拒绝策略(线程池状态不正确)
            reject(command);
        // 线程池是running或者移除任务失败,判断工作线程是否为0,
        else if (workerCountOf(recheck) == 0)
        // 工作线程数为0,但是工作队列中有任务在排队,则任务无人处理
        // 添加一个空任务,非核心线程,为了处理在工作队列中排队的任务
            addWorker(null, false);
    }
    // 添加到任务队列失败,则创建非核心线程执行任务
    // 如果这时创建非核心线程失败(当前线程不小于maximumPoolSize时),就会执行拒绝策略
    else if (!addWorker(command, false))
        reject(command);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值