什么,你理解的线程池流程一直是错的?

1. 前言

我发现很多人对线程池的一个执行流程都有一个误解,很多人理解的线程池的执行流程是这样的

其实中间有一个有大的漏洞,很多人会觉得,只有当阻塞对列满的时候,才会去添加非核心工作线程,包括很多文章或者视频中,都是讲的错的,当我们往阻塞队列添加任务的时候,他并不会傻傻的等待,而是会判断线程池中的一个工作线程,如果工作线程数为零,为了防止线程饥饿,会创建一个非核心工作线程,下面是线程池的execute方法的注释

2. 线程的池的execute方法

// 提交任务到线程池的核心方法
// command就是提交过来的任务
public void execute(Runnable command) {
    // 提交的任务不能为null
    if (command == null)
        throw new NullPointerException();
    // 获取核心属性ctl,用于后面的判断
    int c = ctl.get();
    // 如果工作线程个数,小于核心线程数。
    // 满足要求,添加核心工作线程
    if (workerCountOf(c) < corePoolSize) {
        // addWorker(任务,是核心线程吗)
        // addWorker返回true:代表添加工作线程成功
        // addWorker返回false:代表添加工作线程失败
        // addWorker中会基于线程池状态,以及工作线程个数做判断,查看能否添加工作线程
        if (addWorker(command, true))
            // 工作线程构建出来了,任务也交给command去处理了。
            return;
        // 说明线程池状态或者是工作线程个数发生了变化,导致添加失败,重新获取一次ctl
        c = ctl.get();
    }
    // 添加核心工作线程失败,往这走
    // 判断线程池状态是否是RUNNING,如果是,正常基于阻塞队列的offer方法,将任务添加到阻塞队列
    if (isRunning(c) && workQueue.offer(command)) {
        // 如果任务添加到阻塞队列成功,走if内部
        // 如果任务在扔到阻塞队列之前,线程池状态突然改变了。
        // 重新获取ctl
        int recheck = ctl.get();
        // 如果线程池的状态不是RUNNING,将任务从阻塞队列移除,
        if (!isRunning(recheck) && remove(command))
            // 并且直接拒绝策略
            reject(command);
        // 在这,说明阻塞队列有我刚刚放进去的任务
        // 查看一下工作线程数是不是0个
        // 如果工作线程为0个,需要添加一个非核心工作线程去处理阻塞队列中的任务
        // 发生这种情况有两种:
        // 1. 构建线程池时,核心线程数是0个。
        // 2. 即便有核心线程,可以设置核心线程也允许超时,设置allowCoreThreadTimeOut为true,代表核心线程也可以超时
        else if (workerCountOf(recheck) == 0)
            // 为了避免阻塞队列中的任务饥饿,添加一个非核心工作线程去处理
            addWorker(null, false);
    }
    // 任务添加到阻塞队列失败
    // 构建一个非核心工作线程
    // 如果添加非核心工作线程成功,直接完事,告辞
    else if (!addWorker(command, false))
        // 添加失败,执行决绝策略
        reject(command);
}

3. execute的完整执行流程图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值