并发编程-线程池ThreadPoolExecutor底层原理分析(二)

1、线程池中基本属性和方法源码解析
2、线程池的五种状态变换源码分析
3、线程池添加线程源码解析
4、线程池线程运行执行任务源码解析
5、线程池shutdown源码解析
6、线程池中线程退出机制源码解析

线程池源码的基础属性和方法

在线程池的源码中,会通过一个AtomicInteger类型的变量 ctl ,来表示 线程池的状态 当前线程池中 的工作线程数量
一个Integer占4个字节,也就是32个bit, 线程池有5个状态:
1. RUNNING
2. SHUTDOWN
3. STOP
4. TIDYING
5. TERMINATED
2个bit能表示4种状态,那5种状态就至少需要三个bit位,比如在线程池的源码中就是这么来表示的:
private static final int COUNT_BITS = Integer.SIZE - 3;

 private static final int RUNNING = -1 << COUNT_BITS;
 private static final int SHUTDOWN = 0 << COUNT_BITS;
 private static final int STOP = 1 << COUNT_BITS;
 private static final int TIDYING = 2 << COUNT_BITS;
 private static final int TERMINATED = 3 << COUNT_BITS;
Integer.SIZE为32,所以COUNT_BITS为29,最终各个状态对应的二级制为:
1. RUNNING: 111 00000 00000000 00000000 00000000
2. SHUTDOWN: 000 00000 00000000 00000000 00000000
3. STOP: 001 00000 00000000 00000000 00000000
4. TIDYING: 010 00000 00000000 00000000 00000000
5. TERMINATED: 011 00000 00000000 00000000 00000000
        所以,只需要使用一个Integer数字的 最高三个bit ,就可以 表示5种线程池的状态 ,而 剩下的29个bit 就 可以用来 表示工作线程数 ,比如,假如ctl为: 111 00000 00000000 00000000 0000 1 0 1 0,就表示 线程池的状态为RUNNING,线程池中目前在工作的线程有10个,这里说的“在工作”意思是线程活着,要么在执行任务,要么在阻塞等待任务。
同时,在线程池中也提供了一些方法用来获取线程池状态和工作线程数,比如:
 // 29,二进制为00000000 00000000 00000000 00011101
    private static final int COUNT_BITS = Integer.SIZE - 3;

    // 00011111 11111111 11111111 11111111
    private static final int CAPACITY = (1 << COUNT_BITS) - 1;

    // ~CAPACITY为11100000 00000000 00000000 00000000
    // &操作之后,得到就是c的高3位
    private static int runStateOf(int c) {
        return c & ~CAPACITY;
    }

    // CAPACITY为00011111 11111111 11111111 11111111
    // &操作之后,得到的就是c的低29位
    private static int workerCountOf(int c) {
        return c & CAPACITY;
    }
同时,还有一个方法:
private static int ctlOf(int rs, int wc) {
 return rs | wc;
 }
        就是用来把运行状态和工作线程数量进行合并的一个方法,不过传入这个方法的两个int数字有限制, rs的低29位都得为0,wc的高3位都得为0,这样经过或运算之后,才能得到准确的ctl。
同时,还有一些相关的方法:
 private static final int RUNNING = -1 << COUNT_BITS;
    private static final int SHUTDOWN = 0 << COUNT_BITS;
    private static final int STOP = 1 << COUNT_BITS;
    private static final int TIDYING = 2 << COUNT_BITS;
    private static final int TERMINATED = 3 << COUNT_BITS;

    // c状态是否小于s状态,比如RUNNING小于SHUTDOWN
    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }

    // c状态是否大于等于s状态,比如STOP大于SHUTDOWN
    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }

    // c状态是不是RUNNING,只有RUNNING是小于SHUTDOWN的
    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

    // 通过cas来增加工作线程数量,直接对ctl进行加1
    // 这个方法没考虑是否超过最大工作线程数的(2的29次方)限制,源码中在调用该方法之前会进行判断的
    private boolean compareAndIncrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect + 1);
    }

    // 通过cas来减少工作线程数量,直接对ctl进行减1
    private boolean compareAndDecrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect - 1);
    }



前面说到线程池有5个状态,这5个状态分别表示:
1. RUNNING: 线程池正常运行中,可以正常的接受并处理任务.
2. SHUTDOWN :线程池关闭了, 不能接受新任务
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长情知热爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值