聊聊 ThreadPoolExecutor 线程池及其源码

在我们的实际开发中,通常使用线程池创建线程资源。而线程池本质上是一种池化技术,利用资源复用的思想,复用线程资源。
摘要由CSDN通过智能技术生成

什么是线程池

在我们的实际开发中,通常使用线程池创建线程资源。

而线程池本质上是一种池化技术,利用资源复用的思想,复用线程资源。

为什么使用线程池

那么,我们为什么要使用线程池呢?主要有以下两点原因:

  • 首先,使用线程池可以避免频繁创建和销毁线程所带来的性能开销。因为线程的创建会涉及到 CPU 上下文的切换以及内存的分配。
  • 其次,我们可以通过线程池参数控制线程的数量,避免无休止的创建线程带来的资源利用率过高的问题,从而起到资源保护的作用。

线程池的状态

在我们使用线程池时,一共涉及 5 种状态,其中包括:

  1. RUNNING :能接受新提交的任务,并且也能处理阻塞队列中的任务;

  2. SHUTDOWN:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务。在线程池处于 RUNNING 状态时,调用 shutdown() 方法会使线程池进入到该状态。(finalize() 方法在执行过程中也会调用 shutdown() 方法进入该状态);

  3. STOP:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。在线程池处于 RUNNINGSHUTDOWN 状态时,调用 shutdownNow() 方法会使线程池进入到该状态;

  4. TIDYING:如果所有的任务都已终止了,workerCount (有效线程数) 为 0,线程池进入该状态后会调用 terminated() 方法进入 TERMINATED 状态。

  5. TERMINATED:在 terminated() 方法执行完后进入该状态,默认 terminated() 方法中什么也没有做。进入TERMINATED的条件如下:

    • 线程池不是 RUNNING 状态;
    • 线程池状态不是 TIDYING 状态或 TERMINATED 状态;
    • 如果线程池状态是 SHUTDOWN 并且 workerQueue 为空;
    • workerCount0
    • 设置 TIDYING 状态成功。

线程池的分析及源码

核心属性

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// COUNT_BITS = 32 - 3 = 29
private static final int COUNT_BITS = Integer.SIZE - 3;
// 工作线程的最大个数 
// 00100000 00000000 00000000 00000000 - 1 
// 000111111111111111111111111111111
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

// runState is stored in the high-order bits
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;

其中 ctl 属性维护着线程池的两个重要内容:

  1. 3 位维护着线程池的状态;
  2. 29 位维护着工作线程个数;

ctl 相关方法

// Packing and unpacking ctl
// 获取线程池状态
private static int runStateOf(int c)     { return c & ~CAPACITY; }
// 获取工作线程数
private static int workerCountOf(int c)  { return c & CAPACITY; }
// 获取运行状态和工作线程数的值
private static int ctlOf(int rs, int wc) { return rs | wc; }

ThreadPoolExecutor 构造方法

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
            null :
            AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

可以看出,在 ThreadPoolExecutor 的有参构造器中一共有 6 个参数:

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

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

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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值