JDK之ThreadPoolExecutor(一)

1. 概述

本文首先对Java线程池的整个工作流程做一个概述,之后再对其中一些值得思考的地方做一些源码解读

2. 工作模式

Java的线程池是一个worker thread模式,这个模式非常简单,大概就是这么几点:

  1. 有一个任务队列
  2. 有一批工人
  3. 工人做完手头的工作后从任务队列里获取新的任务
  4. 人手不够的时候考虑增加新的工人
  5. 人手过多的时候,考虑辞退一部分工人~

这个过程差不多就对应着线程池的execute方法,下面我们来看一下相关源码,相关内容已经写在了注释当中

public void execute(Runnable command) {
   
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        // 工作线程小于核心线程数,相当于核心员工还没招够
        // 此时要大规模招聘工人
        if (workerCountOf(c) < corePoolSize) {
   
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        // 工作线程数达到核心线程数,此时尝试将任务放入任务队列
        if (isRunning(c) && workQueue.offer(command)) {
   
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        // 如果任务队列已满,尝试增加新的工作线程,
        // 如果增加新的工作线程失败(达到最大线程数),则根据拒绝策略处理
        else if (!addWorker(command, false))
            reject(command);
    }
}

显然代码中除了我们之前提到的,还有一些别的东西,比如ctl是个什么东西,拒绝策略又是怎么操作的,接下来我们一步步来看这些问题

2. 线程池状态+工作线程数=ctl?

ctl是一个32位的AtomicInteger,其高三位用来表示线程池状态,低29位用来表示工作线程数

所以说,clt的值是可以根据工作线程数和线程池状态拼出来的,其初始化也是根据值拼出来的。为什么不初始化为0?因为虽然工作线程一开始是0,但是线程池状态不是0

ctlOf()方法就是负责拼凑的,其内容也是很容易理解

    private static int ctlOf(int rs, int wc) {
    return rs | wc; }

ctl的初始化

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

一些相关字段

// 这个是用来做位移的,在这里就是29
private static final int COUNT_BITS = Integer.SIZE - 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值