线程池execute源码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/liujunzxcv/article/details/94580451
/**
     * Executes the given task sometime in the future.  The task
     * may execute in a new thread or in an existing pooled thread.
     * 在未来某个时间执行指定传入的任务。
     * 任务可以在一个新线程中执行,也可能在线程池中已存在的一个线程中执行。
     * If the task cannot be submitted for execution, either because this
     * executor has been shutdown or because its capacity has been reached,
     * the task is handled by the current {@code RejectedExecutionHandler}.
     * 如果这个任务不能被提交执行,或者是因为这个executor已经被shutdown,又或者因为已经触及线程池的最大容量,
     * 这个任务被当前的拒绝策略RejectedExecutionHandler处理掉了
     * @param command the task to execute
     * @throws RejectedExecutionException at discretion of
     *         {@code RejectedExecutionHandler}, if the task
     *         cannot be accepted for execution
     * @throws NullPointerException if {@code command} is null
     */
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
         /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         * 如果线程池当前正在运行的线程数小于corePoolSize,将尝试新起一个线程,传入的Runnable command将作为它的第一个任务。
         * 调用addWorker将原子性的检查runState线程池运行状态和workerCount工作者数量,并且当不应该新增线程时通过return false来阻止。
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         * 如果一个任务能够成功的加入队列,这时我们仍然需要再次检查我们是否应该新起一个线程(因为从上次检查之后已存在的线程有可能消亡了)
         * 或者进入此方法后线程池shutdown了。
         * 所以我们还是要重新检查线程池状态,以及当线程池停止是否有必要将入队列的操作回滚,
         * 或者线程池中没有线程时需要新起一个线程
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         * 如果不能将任务入队列,这时我们尝试新起一个线程,如果新起线程失败,我们就知道线程池已经被shutdown或者线程池饱和了,
         * 这时就需要拒绝任务了
         */
       int c = ctl.get();
        //如果worker的数量小于corePoolSize
        if (workerCountOf(c) < corePoolSize) {
            //如果添加任务成功就可以返回了
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //如果workerCount不小于核心线程数,那么接下来尝试放到blockingqueue了
        //ctl<SHUTDOWN且入队列成功
        if (isRunning(c) && workQueue.offer(command)) {
            //二次检查ctl
            int recheck = ctl.get();
            //ctl>=SHUTDOWN且移除任务成功
            if (! isRunning(recheck) && remove(command))
                //拒绝任务
                reject(command);
                //如果workerCount==0,这时候创建空的worker,使用maximumPoolSize
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //接下来是尝试添加超过corePoolSize,<=maximumPoolSize,如果添加失败则采用拒绝策略
        else if (!addWorker(command, false))
            reject(command);
    }
 private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            //得到ctl
            int c = ctl.get();
            //c & ~CAPACITY 只保留高3位状态位1
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            //3种情况,1、线程池>SHUTDOWN
            // 2、线程池状态==SHUTDOWN 且firstTask != null
            // 3、线程池状态==SHUTDOWN 且firstTask == null且workQueue.isEmpty()
            //当firstTask为空时是为了创建一个没有任务的线程,再从workQueue中获取任务,如果workQueue已经为空,那么就没有添加新worker的必要了
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                //workCount
                int wc = workerCountOf(c);
                //如果workCount>=最大线程数容量或者>=core
                //core是传进来的参数,true代表使用corePoolSize计量,false代表使用maximumPoolSize
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                //如果cas操作将WorkerCount+1成功,直接break外层循环,继续往下走
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                //重新get ctl
                c = ctl.get();  // Re-read ctl
                //如果runstate变了就要重新从外层循环开始判断
                if (runStateOf(c) != rs)
                    continue retry;
                //否则走到这里只能是因为workerCount变了导致cas失败,这时重新开始内层循环
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            //new一个worker
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    // Recheck while holding lock.
                    // Back out on ThreadFactory failure or if
                    // shut down before lock acquired.
                    int rs = runStateOf(ctl.get());
                    //若线程池状态<SHUTDOWN或
                    // ==SHUTDOWN且是一个空任务
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        //如果线程已经启动,抛异常
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        //把new worker添加到worker set中
                        workers.add(w);
                        int s = workers.size();
                        //largestPoolSize用来记录线程池线程数曾达到的最大值
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        //标记worker已添加
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                //标记worker已添加到worker set中,启动线程标记为已启动
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            //如果worker未启动,进行添加worker失败的后续处理
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }
  /**
     * Rolls back the worker thread creation.
     * 回滚创建worker线程的操作
     * - removes worker from workers, if present
     * 从worker set移除此worker
     * - decrements worker count
     * worker count递减
     * - rechecks for termination, in case the existence of this
     *   worker was holding up termination
     *   重新检查是否要terminate,防止是由于这个回退worker hold住了线程池使其不能停止
     */
    private void addWorkerFailed(Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (w != null)
                workers.remove(w);
            //循环尝试,直到cas成功,完成计数-1
            decrementWorkerCount();
            //尝试停止线程池
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }
 /**
     * Transitions to TERMINATED state if either (SHUTDOWN and pool
     * and queue empty) or (STOP and pool empty).  If otherwise
     * 如果线程池处于SHUTDOWN状态且线程池及队列都为空,或者STOP且线程池为空,转换成TERMINATED状态
     * eligible to terminate but workerCount is nonzero, interrupts an
     * idle worker to ensure that shutdown signals propagate. This
     * 如果符合terminate的条件但workerCount不为0,则中断一个空闲worker以保证这个shutdown信号被传递
     * method must be called following any action that might make
     * termination possible -- reducing worker count or removing tasks
     * 此方法应该在任何可能导致线程池终止的操作之后被调用,这些操作可能是worker数量被减少或者在shutdown的时候从线程队列移除了任务
     * from the queue during shutdown. The method is non-private to
     * allow access from ScheduledThreadPoolExecutor.
     * 此方法不是私有的,为了能够让ScheduledThreadPoolExecutor访问到
     */
    final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            //c < SHUTDOWN还处于运行状态
            //或者已经是TIDYING或者TERMINATED状态了,就无需再tryTerminate
            //或者状态是SHUTDOWN但工作队列不为空,这时候也不能tryTerminate
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            //如果能再往下走,说明处于SHUTDOWN状态且workQueue是空的
            //如果worker数量不为0,这时候去中断一个空闲的worker,即用中断去唤醒一个阻塞在从workqueue获取任务的core线程,且只中断一个
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                //cas将线程池状态变为TIDYING,workercount变为0
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        //如果cas成功了就调用terminated,这里应该可以看成是一个钩子方法,本身是个空方法,由子类去override
                        terminated();
                    } finally {
                        //最后把ctl设置成TERMINATED,workercount为0
                        ctl.set(ctlOf(TERMINATED, 0));
                        //唤醒那些调用了awaitTermination()等待线程池终止的线程
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

猜你喜欢

转载自blog.csdn.net/liujunzxcv/article/details/94580451
今日推荐