ThreadPoolExecutor 源码分析

ThreadPoolExecutor

// runState is stored in the high-order bits

//能提交新的任务,并且也能处理阻塞队列中的任务
private static final int RUNNING    = -1 << COUNT_BITS;

 

//关闭状态,不再接收新提交的任务,但却可以继续处理阻塞队列中的任务
private static final int SHUTDOWN   =  0 << COUNT_BITS;

 

//不接受新任务,也不处理阻塞队列中的任务,会中断正在处理任务的线程
private static final int STOP       =  1 << COUNT_BITS;

 

//所有任务已经终止,workerCount(有效线程)为0
private static final int TIDYING    =  2 << COUNT_BITS;

 

//在terminated方法执行完成后进入改状态
private static final int TERMINATED =  3 << COUNT_BITS;

 

 

核心方法

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();//ctl 高三位 记录线程状态 后29位记录线程数

//计算当前线程数是否小于核心线程数,如果小于直接创建线程去执行
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }

//如果当前线程数正在运行并且阻塞队列未满

//执行阻塞队列的头结点任务(FIFO)
    if (isRunning(c) && workQueue.offer(command)) {

//判断当前的线程状态如果不在运行,remove掉任务,拒绝任务的执行
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);

//如果当前有效线程数位0 ,不会把新的任务添加进去
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }

//如果当前线程数大于核心线程数队列也满了,但是最大线程数没满尝试创建新的线程去执行,如果创建不了,就拒绝任务执行
    else if (!addWorker(command, false))
        reject(command);
}

 

 

private static int workerCountOf(int c)  { return c & CAPACITY; }

 

 

 

 

 

/**
 * Checks if a new worker can be added with respect to current
 * pool state and the given bound (either core or maximum). If so,
 * the worker count is adjusted accordingly, and, if possible, a
 * new worker is created and started, running firstTask as its
 * first task. This method returns false if the pool is stopped or
 * eligible to shut down. It also returns false if the thread
 * factory fails to create a thread when asked.  If the thread
 * creation fails, either due to the thread factory returning
 * null, or due to an exception (typically OutOfMemoryError in
 * Thread.start()), we roll back cleanly.
 *
 * @param firstTask the task the new thread should run first (or
 * null if none). Workers are created with an initial first task
 * (in method execute()) to bypass queuing when there are fewer
 * than corePoolSize threads (in which case we always start one),
 * or when the queue is full (in which case we must bypass queue).
 * Initially idle threads are usually created via
 * prestartCoreThread or to replace other dying workers.
 *
 * @param core if true use corePoolSize as bound, else
 * maximumPoolSize. (A boolean indicator is used here rather than a
 * value to ensure reads of fresh values after checking other pool
 * state).
 * @return true if successful
 */
private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);//获取当前的状态

        // Check if queue empty only if necessary.

//如果当前状态是不是正在运行状态 并且提交的任务不为空或者阻塞队列为空 直接返回false,也就是创建新线程失败了,此时可能是刚开始执行时也可能是核心线程满了队列也满了,但最大线程数没满,所以这里判断阻塞队列为非空,如果为非空还需要继续执行队列里面的任务
        if (rs >= SHUTDOWN &&
            ! (rs == SHUTDOWN &&
               firstTask == null &&
               ! workQueue.isEmpty()))
            return false;

//自旋操作

//判断条件是 不能大于核心线程数或者最大线程数 根据core来判断 core在executor中传入

//此时是工作线程+1操作可能多个线程一起在操作这里用cas来控制这个操作,成功就退出循环,否则就自旋,直到操作成功
        for (;;) {
            int wc = workerCountOf(c);
            if (wc >= CAPACITY ||
                wc >= (core ? corePoolSize : maximumPoolSize))
                return false;
            if (compareAndIncrementWorkerCount(c))
                break retry;
            c = ctl.get();  // Re-read ctl
            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) {
            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());

//判断线程池状态

//满足后 就执行了
                if (rs < SHUTDOWN ||
                    (rs == SHUTDOWN && firstTask == null)) {
                    if (t.isAlive()) // precheck that t is startable
                        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;
}

 

任务分发

private Runnable getTask() {
    boolean timedOut = false; // Did the last poll() time out?
//自旋操作  获取任务,
    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);

        // Check if queue empty only if necessary.     

//判断线程池当前的状态  为什么加上后面的&&

// 因为当先城状态是shutdown时还会处理阻塞队列中的任务,所以只有die或者terminal的或者祖册队列中任务时才会返回null

   if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }

        int wc = workerCountOf(c);//获取工作线程数

        // Are workers subject to culling?

//如果任务执行超时了 或者已经超过了最大线程数 更新工作线程数返回null也就是没获取到任务
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

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

//超时就移除否则就取头节点  如果没有节点的话  就会阻塞在这里

//这里的timed值的是上面设置的允许超时或者超过核心线程数,为什么超过核心线程数就是timed了?未超过核心线程数是直接创建线程执行的,只有超过核心线程了才会往blockQuene中添加,如果timed了就移除这个,否则就取头节点 如果blockQuene中没有节点,就会阻塞在这里
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) ://超过时间获取到移除的元素也就是队列中没有元素
                workQueue.take();
            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

 

 

posted @ 2020-06-08 14:21  王南辉  阅读(92)  评论(0)    收藏  举报