线程池

1110 0000 0000 0000 0000 0000 0000 0000 Runing
0000 0000 0000 0000 0000 0000 0000 0000 SHUTDOWN
0010 0000 0000 0000 0000 0000 0000 0000 STOP
0100 0000 0000 0000 0000 0000 0000 0000 TIDYING
1100 0000 0000 0000 0000 0000 0000 0000 TERMINATED

0001 0000 0000 0000 0000 0000 0000 0000
1110 0000 0000 0000 0000 0000 0000 0000
workerCountOf© < corePoolSize 第一次可以进入 workerCountOf返回来的值是0

addWork中的 int c = ctl.get();; 返回来的值 如下
1110 0000 0000 0000 0000 0000 0000 0000

if (runStateAtLeast(c, SHUTDOWN) 返回来的值是false
&& (runStateAtLeast(c, STOP)
|| firstTask != null
|| workQueue.isEmpty()))
return false;

addWorker这个方法 将任务添加到work中工作中
每个线程有对应的一个方法栈 然后自旋 拿到for (int c = ctl.get();😉 拿到c的值记录在方法栈中
然后多线程工作 每个线程都会记录一个c的值 到方法栈中的局部变量表中
然后通过CAS更新到AtomicInteger 原子类中
if (compareAndIncrementWorkerCount©)
break retry;
每个线程可能会有1毫秒的差距 然后先的线程添加成功会调出死循环 执行下面的代码

如果没有成功就一直会再这个循环里面一直死循环 直到成功为止
for (;😉 {
if (workerCountOf©
>= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
return false;

            if (compareAndIncrementWorkerCount(c))
                break retry;
线程会再次拿到c的值 
            c = ctl.get();  // Re-read ctl
            
if (runStateAtLeast(c, SHUTDOWN))
                continue retry;
            // else CAS failed due to workerCount change; retry inner loop
        }

private boolean addWorker(Runnable firstTask, boolean core) {
retry:
//最开始线程进来就拿到c的值 保存在线程栈中的局部变量表中 存储c
for (int c = ctl.get();😉 {
// Check if queue empty only if necessary.
//当我们调用Shutdown方法时,就不能往worker中添加,并且不用添加到队列中,但是要处理队列中的任务
进入线程会第一个时间判断这个条件,这是因为,当我们创建了一个线程池,我们第一时间就调用Shutdown方法,并且之后才调用了Submit或者excite方法就会对线程中的任务抛出一个异常,因为第一次没有任务 ,如果 当我们传进来的firstTask 不为空 并且我们调用了 Shutdown这个方法 就会返回false
if (runStateAtLeast(c, SHUTDOWN)
&& (runStateAtLeast(c, STOP)
|| firstTask != null
|| workQueue.isEmpty()))
return false;

        for (;;) {
   //当我们多个线程都执行了成功的时候 并且core 的值为true 就会判断线程的数量>核心数量的线程 就会返回false
            if (workerCountOf(c)
                >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
                return false;
//直到成功为止 如果一个线程进入这个方法没有添加成功 就会返回False
再次拿到c的值 这个时候c的值已经被改变 改变的值是就上一个线程更改的值
            if (compareAndIncrementWorkerCount(c))
                break retry;   //这个时候会跳出所以的循环
            c = ctl.get();  // 如果上面的方法没有更新成功 没有更新成功的原因就是由一个线程已经对主存里面的值 已经更新了 所以另外一个线程去更新的时候 主存里面的值已经更改  所以线程会在此拿到c的值
            //这个方法就是我们用户去对线程池调用shutdown 方法 
就会跳出第二个死循环 执行第一个循环 自旋到第一个判断
if (runStateAtLeast(c, SHUTDOWN))
                continue retry;
            // else CAS failed due to workerCount change; retry inner loop
        }

     boolean workerStarted = false;   //worker线程开始的初始值
    boolean workerAdded = false;   //worker线程添加成功的初始值
    Worker w = null;
    try {   每个线程进来都会对worker的内部类创建一个对象
        w = new Worker(firstTask);
        final Thread t = w.thread;
        if (t != null) {    <----- 每个线程都会进入到这个地方 
            final ReentrantLock mainLock = this.mainLock; //但是对下面的操作进行了Lock的操作 并让单个线程执行下面的操作,保证添加到HashSet方法中的是一个单线程的操作  
            mainLock.lock();
            try {
    // 如果第一个线程拿到了锁,就会进去 ,其余的线程进行阻塞状态,拿到第一个c的值           
                int c = ctl.get();
          如果c的值是Runing状态就返回成功  (或者 c 的值是比Stop小并且fristTask等于Null )也会进入下面的操作 
      为什么要保证fistTask为null 这个是因为 当我们调用了ShutdownNow时 他会将线程改成Stop状态,Stop状态保证了不能添加,也不用处理阻塞队列中的任务  	
                if (isRunning(c) ||  (runStateLessThan(c, STOP) && firstTask == null)) {
                    if (t.getState() != Thread.State.NEW)
                        throw new IllegalThreadStateException();
                    //添加到HasHset当中 添加里面的数量	
                     
          workers.add(w);
        //但我们出现了异常 并且添加进去了 线程就没有开启
                    workerAdded = true;
                    int s = workers.size();
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                }
            } finally {
                mainLock.unlock();
            }
   //这里没有进去 workerStarted 就会返回false
            if (workerAdded) {
                t.start();
                workerStarted = true;
            }
        }
    } finally {
 //就会移除刚刚新添加进去的线程 返回false
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;

}

public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//如果工作线程的数量小于<核心线程的数量就会添加到addWorker中 如果返回false 就会重新回去值
//workerCount的值就是线程数量的值 用&运算 将一个int 值分为前3个表示状态,后29位表示线程数量
if (workerCountOf© < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning© && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值