美文网首页
6、线程池之addWorker

6、线程池之addWorker

作者: kele2018 | 来源:发表于2020-03-17 13:27 被阅读0次
private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);
            //&&实质上是在缩小范围
            if (rs >= SHUTDOWN &&
                //当线程池的状态是shutdown,队列中还有任务时,可以添加worker,但跟随这个worker进来的任务必须为空
                !(rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()))
                return false;
            /**
             * 上面没有阻断 意味着两种情况
             * 1、线程池的状态是running
             * 2、线程池的状态是shutdown,但是队列中还有需要执行的任务,而且跟随这次的worker进来的任务为空(这实质上保证了在shutdown状态下,我们可以执行完队列中的任务)
             */
            for (;;) {
                int wc = workerCountOf(c);

                if (wc >= CAPACITY |
                 /**
                 * core是true,用核心线程数检查
                 * core是false,用最大线程数检查
                 **/
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                //假如这个原子操作成功,说明有人修改了c的值,这时我们再用c去计算,就会得到错误的结果
                if (compareAndIncrementWorkerCount(c))//增加worker的数量就是在这里
                    break retry;
                //有人修改了c,我们获取新的c
                c = ctl.get();  // Re-read ctl
                //看一下他们改的是状态还是worker数量
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            //什么情况会拿不到线程呢?
            if (t != null) {
                //为什么又要做一个引用指向mainLock?
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    int rs = runStateOf(ctl.get());
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        //workers的结构为什么要用hashset?
                        workers.add(w);//同一时刻只能有一个线程向workers中添加worker
                        int s = workers.size();
                        //这个largestPoolSize有啥用?比它大了,就更新
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

相关文章

网友评论

      本文标题:6、线程池之addWorker

      本文链接:https://www.haomeiwen.com/subject/vrhtyhtx.html