线程池的执行流程

添加任务到线程池

  1. 判断任务是否为空, 任务为空,结束。
  2. 任务不为空,判断能否创建核心线程,若能创建,结束
    能否创建核心线程((ctl的29位,设置的corepoolsoze 共同判断)
    创建核心线程会存在失败的情况,假设设置核心线程数位5,已经创建了4个,还剩1个,此时A和B都来创建,只有一个能创建成功。
  3. 若核心线程没有创建成功,或者已经到达设置的核心线程数的值了,则判断线程池状态是否正常,若线程池状态是Running状态,就可以把任务添加到阻塞任务。若成功把任务扔到阻塞队列中判断当前工作线程是否是0个若是,则添加一个非核心工作线程处理,添加成功,结束。若不是,结束
    判断当前工作线程是否是0个,记住,核心线程数是可以设置为0个的。
    添加到阻塞任务也会存在失败情况,比如只剩最后一个位置,2个线程同时添加,就会存在失败的情况。
    当把任务扔到阻塞队列中,一定要保证有工作线程处理它。
  4. 若添加工作线程失败,当在阻塞任务中扔任务后发现,线程池状态不是Running状态了,则执行拒绝策略,执行完毕,结束。
    存在在阻塞任务中扔任务前,线程池状态是Running状态
    阻塞任务中扔任务后,线程池状态不是Running状态。
  5. 当阻塞队列放满了,线程池状态是Running状态,尝试添加非核心工作线程,若成功添加,结束。若失败,则执行拒绝策略,结束。
    添加非核心工作线程,(ctl的29位, 设置的max 最大线程数 共同判断)
    在这里插入图片描述
    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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值