ThreadPool源码学习

69 阅读4分钟

思考一个问题:

线程池状态:核心线程数为 2,最大线程数为2,阻塞队列为有界队列长度为3

在使用线程池添加一个任务时,如果此时:阻塞队列为满,且核心线程的两个数同时完成,那此时任务会直接用核心线程执行吗?

一、线程池的核心参数:

  • corePoolSize,核心线程数
  • maximumPoolSize,最大线程数
  • keeAliveTime,空闲存活时间
  • unit,空闲存活时间单位
  • workQueue,工作队列
  • threadFactory,线程工场
  • handle,拒绝策略

二、线程池的状态(占用ctl的前三位)

  • RUNNING(-1<<29) 111;运行状态,线程池创建好之后就会进入此状态,如果不手动调用关闭方法,那么线程池在整个程序运行期间都是此状态。
  • SHUTDOWN(0<<29)000;关闭状态,不再接受新任务提交,但是会将已保存在任务队列中的任务处理完。
  • STOP(1<<29)001;停止状态,不再接受新任务提交,并且会中断当前正在执行的任务、放弃任务队列中已有的任务。
  • TIDYING(2<<29)010;整理状态,所有的任务都执行完毕后(也包括任务队列中的任务执行完),当前线程池中的活动线程数降为 0 时的状态。到此状态之后,会调用线程池的 terminated() 方法。
  • TERMINATED(3<<29)011;销毁状态,当执行完线程池的 terminated() 方法之后就会变为此状态。

状态变化图

线程池状态变化图.png

三、execute()方法执行逻辑(提交任务)

    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.
         *
         * 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.
         *
         * 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.
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            //如果当前线程数小于核心线程数,则创建和核心线程并执行任务
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            //如果线程池为运行状态且workQueue未满,将任务加入阻塞队列
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                //如果线程池不是运行状态并且能够从阻塞队列中移除了该任务,则对该任务执行拒绝策略
                reject(command);
            else if (workerCountOf(recheck) == 0)
                //如果工作线程为0则创建工作线程
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

四、addWorker() 方法(添加线程)

 private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (int c = ctl.get();;) {
            // Check if queue empty only if necessary.
            //检查线程池状态,如果是shutdown及以上的状态(shutdown,stop,tidying)且 
            //已停止或者没有任务或者工作队列为空
            if (runStateAtLeast(c, SHUTDOWN)
                && (runStateAtLeast(c, STOP)
                    || firstTask != null
                    || workQueue.isEmpty()))
                return false;

            for (;;) {
                //如果线程数达到核心线程数或者总线程数上限,则返回创建线程失败
                if (workerCountOf(c)
                    >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK)
                   )
                    return false;
                //如果增加线程数成功,跳出retry循环
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateAtLeast(c, SHUTDOWN))
                    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) {
                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 c = ctl.get();
					
                    if (isRunning(c) ||
                        (runStateLessThan(c, STOP) && firstTask == null)) {
                        //如果线程池是运行状态或 处于shutdown状态且无任务
                        if (t.getState() != Thread.State.NEW)
                            //如果线程不是NEW状态则抛出异常
                            throw new IllegalThreadStateException();
                        //添加工作线程到workers集合并更新当前线程数量
                        workers.add(w);
                        workerAdded = true;
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

五、runWork()方法(执行任务)

final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    //如果线程池处于STOP状态或 
                    //当前线程被中断且线程池至少是STOP状态去且工作线程没被中断,则中断工作线程
                    wt.interrupt();
                try {
                    //任务执行前处理
                    beforeExecute(wt, task);
                    try {
                        task.run();
                        //任务执行后处理
                        afterExecute(task, null);
                    } catch (Throwable ex) {
                        afterExecute(task, ex);
                        throw ex;
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            //处理工作线程退出
            processWorkerExit(w, completedAbruptly);
        }
    }

六、getTask()线程获取任务方法

private Runnable getTask() {
    boolean timedOut = false; // Did the last poll() time out?

    for (;;) {
        int c = ctl.get();

        // Check if queue empty only if necessary.
        if (runStateAtLeast(c, SHUTDOWN)
            && (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }

        int wc = workerCountOf(c);

        // Are workers subject to culling?
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

七、processWorkerExit()处理工作线程退出方法

    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            //如果处于shutdown或者running状态
            if (!completedAbruptly) {
                //allowCoreThreadTimeOut 是否开启核心线程超时等待,默认为false
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);
        }
    }