(jdk12)addWorker源代码分析

(jdk12)addWorker源代码分析:

/*
常量说明:

int corePoolSize:核心线程数量,默认情况下,即时没有任务,线程池也会维持核心线程不被销毁;
int maximumPoolSize:最大线程数量,当没有空闲线程可用时,线程池会创建新线程来执行任务,线程总数不会超过此属性;
long keepAliveTime:线程空闲时间,超过该时间后,线程池会销毁线程,默认情况下,核心线程不会被销毁;
TimeUnit unit:线程空闲时间的时间单位;
BlockingQueue workQueue:任务缓存队列,当线程数已达最大数量,且没有空闲线程时,新任务会入队等待;
ThreadFactory threadFactory:创建线程使用的线程工厂,其中可以设置线程名称,方便在日志中排查问题;
RejectedExecutionHandler handler:拒绝策略,当任务缓存队列满后,新收到的任务会交由拒绝策略处理。

最后三个属性应当按照实际业务需求进行实例化,而非使用Executors提供的默认实现。
*/

private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (int c = ctl.get();😉 {

    // Check if queue empty only if necessary.

    if (runStateAtLeast(c, SHUTDOWN)
        && (runStateAtLeast(c, STOP)
  //⬆️判断当前的线程池处于STOP状态或TIDYING状态或TERMINATED状态
            || firstTask != null

//当前线程池没有任务
|| workQueue.isEmpty()))
//当前阻塞队列中没有待执行任务
return false;

    for (;;) {
        if (workerCountOf(c)
            >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))

/*
对于boolean类型core的说明: if true use corePoolSize as bound, else maximumPoolSize. 和COUNT_MASK相与操作表示取低29位,即取core选取的值的后29位表示容量
*/
return false;

/*
⬆️如果线程数量超过了最大容量,这时候addWorker方法返回的值是false。注意⚠️corePoolSize和maximumPoolSize只需要选取其中的值进行容量判断即可。
/
if (compareAndIncrementWorkerCount©)
break retry;
/

通过查询API得知:compareAndIncrementWorkerCount(c)方法用于比较线程池的ctl和当前线程池的WorkerCount(低29位+1)之后大小的,如果超过表示当前线程池已经满了,没有办法添加线程,跳出retry
*/

        c = ctl.get();  // Re-read ctl
        if (runStateAtLeast(c, SHUTDOWN))

//如果clt的高三位没有变成RUNNING,即c>=SHUTDOWN那么返回true,表示线程池状态变更失败,retry
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}

//线程池状态clt修改完毕,开始添加线程

boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;

//⬆️设置线程添加判断位(workerAdded)和 线程运行位(workerStarted)创建新线程Worker w = null

try {
    w = new Worker(firstTask);

//⬆️将传入的runnable类作为新建线程的firstTask

    final Thread t = w.thread;

//⬆️将w的Runnable类的线程传给t
//thread方法说明:Thread this worker is running in. Null if factory fails.

    if (t != null) {

//⬆️判断w线程所使用的Runnable能否成功运行,如果不行返回null

//确认新建线程t和Worker类w创建初始化成功之后,开始创建锁
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
//⬆️创建并持有锁

        try {
            // Recheck while holding lock.
            // Back out on ThreadFactory failure or if
            // shut down before lock acquired.

//⬆️try的目的是在持有锁的期间再次确认,当线程t的Runnable类是否出错,在持有锁的期间这个线程池是否被关闭,如果出现其中一种情况,退出添加线程池的方法
int c = ctl.get();

            if (isRunning(c) ||
                (runStateLessThan(c, STOP) && firstTask == null)) {

/*确定线程池状态为:要么是RUNNING,要么是SHUTDOWN状态(即不再创建新线程,但会把阻塞队列中的任务执行完)且fistTask为空(firstTask是用户传入的Runnable任务)如果为空,那么无需创建新线程进行执行,也满足线程池SHUTDOWN状态的定义。
*/
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();

/*确认完线程池正处于可添加线程的状态之后,确保要添加的新线程已经开始,但还没死亡
API解释isAlive的注释:
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
*/
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
//⬆️在线程池中添加的Worker类,即新建线程,修改相关参数:线程池的容量参数largestPoolSize,注意这个largestPoolSize只能在持有锁mainLock的状态下访问
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
//⬆️放弃锁mainLock的持有权,判断线程池中添加新线程的操作是否成功,如果成功,线程开始运行,线程池也开始运行,如果失败调用,调用addWorkerFailed方法,即删除Worker类的w,修改WorkerCount(线程池房钱线程数量wc)并尝试关闭线程池的方法,返回线程是否开始运行的判断值workerStarted;。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值