ThreadPoolExecutor源码解析

ThreadPoolExecutor中有一个非常重要的变量ctl

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

ctl存储了两个概念上的参数:workCount和runState。
高3位存储运行状态runState
低29位表示表示线程数量workCount

Executor存在以下运行状态:RUNNING < SHUTDOWN < STOP < TIDYING < TERMINATED
RUNNING:接收新的task,处理队列中的task
SHUTDOWN:不接收新的task,继续处理队列中的task
STOP:不接收新的task,不再处理队列中的task,中断正在处理的task
TIDYING:所有的task都终止了,线程数量为0,TIDYING状态将调用terminate()钩子方法
TERMINATED:terminate()方法完成

首先看最重要的execute方法

    public void execute(Runnable command) {
        ...
        int c = ctl.get();
        //   线程数量小于corePoolSize,创建核心线程
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {  // task入队列
            int recheck = ctl.get();
            //不是RUNNING状态,移除task
            if (! isRunning(recheck) && remove(command))
                reject(command);
            //如果在运行阶段,但是Worker数量为0,创建一个线程
            else if (workerCountOf(recheck) == 0)  
                addWorker(null, false);
        }
        // 线程数量小于maximumPoolSize,创建非核心线程
        else if (!addWorker(command, false))
            reject(command);
    }

task入队列后,重新检查运行状态,如果不是RUNNING状态,会移除task
如果是RUNNING状态,检查线程数,如果线程数为0(Executor没有常驻线程),创建一个线程。
addWorker第一个参数为null是正常的,后面说到。

addWorker方法负责创建一个新的线程

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

            // CODE1
            // SHUTDOWN 状态还可以添加线程处理队列的task
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&  
                   firstTask == null &&  // 添加线程而不是添加task
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);
                // 是否为核心线程 
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                if (compareAndIncrementWorkerCount(c))
                    break retry;    // 跳出retry
                c = ctl.get();  
                if (runStateOf(c) != rs)    // State已经发生变化
                    continue retry; // 重新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);  // 创建Worker
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    // 获取锁后再次检查状态
                    int rs = runStateOf(ctl.get());
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // 检查线程是否已启动
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();  // 启动线程
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

retry有两个循环,外循环是用于重复检查状态,内循环是为了保证compareAndIncrementWorkerCount(c)CAS成功。

SHUTDOWN状态时,Executor不接收新的task,但还要处理队列中的task,所以还是可以添加线程。
firstTask为null,表示添加新的线程。这就是CODE1的第二个判断条件。

Worker实现了Runnable,run方法调用runWorker

    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) {  // getTask() == null,该线程退出
                w.lock();  // 防止shutdown时终结正在运行的worker
                // CODE2
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    ...忽略异常处理
                    // 运行task
                    task.run();
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            // exit处理
            processWorkerExit(w, completedAbruptly);
        }
    }

CODE2处,如果Executor为STOP状态,中断线程,否则,清除线程中断标识。

  1. 满足条件state >= STOP&&!wt.isInterrupted(),中断线程
  2. 调用Thread.interrupted,返回并清除中断标识,
    如果返回已中断标识,重新检查state, 如果state >= STOP(这时候!wt.isInterrupted()肯定满足,因为中断标识已清除),中断线程,否则不处理(这是中断标识已清除)。

firstTask为null时,会继续调用getTask,获取队列中的task处理,所以firstTask为null的Worker实际上用于添加线程而不是task。

getTask会获取一个待处理的任务

    private Runnable getTask() {
        boolean timedOut = false; // 是否已等待超时

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

            // 检查状态
            // rs >= STOP || (rs == SHUTDOWN && workQueue.isEmpty())
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();  // 减少WorkerCount
                return null;  // 返回null将结束线程
            }

            int wc = workerCountOf(c);

            // 是否超时等待
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            // 两个条件
            // 1. wc > maximumPoolSize(不正常情况) 或者等待超时
            // 2. wc > 1 || workQueue.isEmpty(),也就是说只有一个线程而且workQueue不是空的,不可以结束线程
            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))  // 减少WorkerCount
                    return null;
                continue;
            }

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

allowCoreThreadTimeOut 允许核心线程超时退出。

看看shutdown方法

    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 检查shutdown权限
            checkShutdownAccess();
            // 设置状态为SHUTDOWN
            advanceRunState(SHUTDOWN);
            // 中断空闲线程
            interruptIdleWorkers();
            // 调用预留方法
            onShutdown(); 
        } finally {
            mainLock.unlock();
        }
        // Terminate
        tryTerminate();
    }

shutdown方法进入SHUTDOWN状态。

shutdownNow与shutdown类型,只是它不是中断空闲线程,而是中断所有线程,并且进入stop状态

    public List shutdownNow() {
        List tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);
            interruptWorkers();
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

看看tryTerminate,该方法在所有task都终止,所有线程都退出后,依次进入TIDYING,TERMINATED状态。

    final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            // 检查状态
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))  // 检查workQueue
                return;
            // 检查workerCount
            if (workerCountOf(c) != 0) {
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                // 设置状态为TIDYING
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        // 调用terminated方法
                        terminated();
                    } finally {
                        // 设置状态为TERMINATED
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

for循环保证ctl.compareAndSet(c, ctlOf(TIDYING, 0))操作成功。
如果workerCount不为0,会中断一个空闲线程。

shutdown/shutdownNow都不是立刻进入Terminate状态。

那么什么时候进入Terminate,在processWorkerExit。
completedAbruptly表示异常退出,runWorker方法中的beforeExecute如果抛出异常,completedAbruptly为true

    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // 正常情况下,getTask返回null时会decrementWorkerCount
            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)) {
            if (!completedAbruptly) {  // 正常退出
                // 最小线程数
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)  
                    return; // replacement not needed
            }
            // 异常退出或者workerCount小于最小线程数,需要添加线程
            addWorker(null, false);
        }
    }
    

当所有Worker都processWorkerExit了,就可以进入Terminate了。

submit

submit会返回一个Future对象,这里看一个Future是怎样生成的

    public Future submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

主要是创建一个FutureTask。

FutureTask后面再解析。

你可能感兴趣的:(ThreadPoolExecutor源码解析)