Android 并发编程(一) - ThreadPoolExecutors 源码详解&运行原理

官方文档

https://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor

如果能好好阅读官方文档,也就不太需要阅读这篇文章了。。。

ThreadPoolExecutors运行图

按照自己对源码的理解,画了一个图,且看且珍惜。。。

Android 并发编程(一) - ThreadPoolExecutors 源码详解&运行原理_第1张图片

带着疑问阅读源码??

  1. 线程池是如何节省线程频繁创建和销毁的开销的呢??
  2. 核心线程是如何保持永驻在线程池中呢?
  3. 非核心线程是如何在keepAliveTime超时后销毁的呢?
  4. WorkQueue有无边界对线程池处理Runnable有什么影响?初始化线程池时,workQueue可以为非空么?

源码详解

常量详解

不看懂这些,后续代码也很难看懂吧~

/**
 * 主池子的控制状态ctl,是一个原子整数,包含两个含义的字段
 * workerCount 表示当前有效的线程数
 * runState 表示运行状态,是否正在运行、关闭等
 * The main pool control state, ctl, is an atomic integer packing
 * two conceptual fields
 *   workerCount, indicating the effective number of threads
 *   runState,    indicating whether running, shutting down etc
 *
 * 为了将这两个字段打包进一个int,我们限制workerCount在(2^29)-1而不是(2^31)-1
 * 如果这在将来是个问题,可以把变量改成AtomicLong类型,并调整移位和掩码常数
 * 但是在需要之前,使用int可以使代码更快以及使用更简单。
 * In order to pack them into one int, we limit workerCount to
 * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
 * billion) otherwise representable. If this is ever an issue in
 * the future, the variable can be changed to be an AtomicLong,
 * and the shift/mask constants below adjusted. But until the need
 * arises, this code is a bit faster and simpler using an int.
 *
 * workerCount 是当前已经被允许启动并不允许停止的worker数量
 * 该值可能与当前实际存活的线程数量不同,举个例子,当一个ThreadFactory创建一个线程失败了,并且即将退出的线程在终止之前仍然在执行。
 * 用户可见的pool size就是当前workers的大小。
 * The workerCount is the number of workers that have been
 * permitted to start and not permitted to stop.  The value may be
 * transiently different from the actual number of live threads,
 * for example when a ThreadFactory fails to create a thread when
 * asked, and when exiting threads are still performing
 * bookkeeping before terminating. The user-visible pool size is
 * reported as the current size of the workers set.
 *
 * runState变量提供主要生命周期控制,具有以下值:
 *  RUNNING:  接受新的任务并且处理正在排队的任务
 *  SHUTDOWN:不接受新的任务,但是处理正在排队的任务
 *  STOP:不接受新的任务,不处理正在排队的任务,打断目前正在处理的任务
 *  TIDYING:所有的任务都已经终止,workerCount为零,线程转换到TIDYING状态,并且即将执行terminated()函数。
 *  TERMINATED:terminated()函数执行完成。
 * The runState provides the main lifecycle control, taking on values:
 *
 *   RUNNING:  Accept new tasks and process queued tasks
 *   SHUTDOWN: Don't accept new tasks, but process queued tasks
 *   STOP:     Don't accept new tasks, don't process queued tasks,
 *             and interrupt in-progress tasks
 *   TIDYING:  All tasks have terminated, workerCount is zero,
 *             the thread transitioning to state TIDYING
 *             will run the terminated() hook method
 *   TERMINATED: terminated() has completed
 *
 * 
 * The numerical order among these values matters, to allow
 * ordered comparisons. The runState monotonically increases over
 * time, but need not hit each state. The transitions are:
 *
 * RUNNING -> SHUTDOWN 当调用shutdown()或finalize()函数
 *    On invocation of shutdown(), perhaps implicitly in finalize()
 * (RUNNING or SHUTDOWN) -> STOP 当调用shutdownNow()
 *    On invocation of shutdownNow()
 * SHUTDOWN -> TIDYING 当workers和workQueue都是空的时候
 *    When both queue and pool are empty
 * STOP -> TIDYING 当workers是空的时候 
 *    When pool is empty
 * TIDYING -> TERMINATED 当terminated()函数执行完成
 *    When the terminated() hook method has completed
 *
 * 当state是TERMINATED的时候,那些在awaitTermination()函数中等待的线程,会立即返回
 * Threads waiting in awaitTermination() will return when the
 * state reaches TERMINATED.
 *
 * 检测状态从SHUTDOWN到TIDYING是比较困难的,因为在SHUTDOWN状态时,workQueue可能会在空和非空切换,所以我们只有在workerCount为0时,终止。
 * (有时我们需要重复检测state,see below。。。)
 * Detecting the transition from SHUTDOWN to TIDYING is less
 * straightforward than you'd like because the queue may become
 * empty after non-empty and vice versa during SHUTDOWN state, but
 * we can only terminate if, after seeing that it is empty, we see
 * that workerCount is 0 (which sometimes entails a recheck -- see
 * below).
 */
// 以下的操作符合前文说的,将 workerCount 和 runState打包在一个int里
// 高3位表示runState,低29位表示workerCount
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; // 29
private static final int CAPACITY   = (1 << COUNT_BITS) - 1; // 2^29 - 1 = 536870911

// runState is stored in the high-order bits
// runState存储在高位
// 最高位代表符号位,1 为负数 0 为正数
private static final int RUNNING    = -1 << COUNT_BITS; // 10100000 00000000 00000000 00000000 -2^29 -536870912
private static final int SHUTDOWN   =  0 << COUNT_BITS; // 00000000 00000000 00000000 00000000
private static final int STOP       =  1 << COUNT_BITS; // 00100000 00000000 00000000 00000000 2^29 536870912
private static final int TIDYING    =  2 << COUNT_BITS; // 01000000 00000000 00000000 00000000 2^30 1073741824
private static final int TERMINATED =  3 << COUNT_BITS; // 01100000 00000000 00000000 00000000 2^30+2^29 1610612736

// Packing and unpacking ctl
private static int runStateOf(int c)     { return c & ~CAPACITY; }
private static int workerCountOf(int c)  { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }

构造函数-ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize, /* 指定线程池中核心线程的数量,即使是空闲状态,也存在线程池中,除非设置了allowCoreThreadTimeOut变量 */
                          int maximumPoolSize,   /* 指定线程池中最大线程数量 */ 
                          long keepAliveTime,  /* 当前线程数量大于核心线程数量时,空闲线程终止等待新任务的最大超时时间 */
                          TimeUnit unit, /* keepAliveTime 的单位 */
                          BlockingQueue workQueue, /* 这个队列将保存待执行的任务 */
                          ThreadFactory threadFactory, /* 用于executor创建线程的工厂 */
                          RejectedExecutionHandler handler) { /* 当达到了线程池的数量边界,或达到了队列的容量,终止执行的处理handler */
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

execute()函数

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    /*
     * Proceed in 3 steps:
     * 处理分3步:
     * 
     * 1.如果当前运行的线程数量小于corePoolSize,则尝试用Runnable command作为它的第一个task来启动一个新的线程。
     * 调用addWorkder函数,这个函数中会以原子的方式来检查runState和workerCount,它会通过return false来防止那些不应该添加线程时出现的警告。
     *(比如workerCount大于CAPACITY 或者 大于 corePoolSize or maximumPoolSize)
     * 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.如果command能够成功插入workQueue,我们需要进行二次检查来判断是否我们需要添加一个新的线程
     * (因为上次检查之后,之前的工作线程已经died,或者线程池的状态改变了)
     * 所以我们需要重新检测runState,如果线程池停止了,我们会remove之前的commnad 并且 拒绝这个command;如果当前workerCount为0,我们会启动一个新的线程
     * 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.如果我们插入command不成功,我们会尝试启动一个新的线程。
     * 如果失败了,我们知道线程池已经shut down或者已经达到饱和状态了,所以我们拒绝这个command。
     * 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)) // 尝试创建核心线程,处理command
            return;
        c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) { // 尝试排队
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false); // Runnable为null时,runWorker方法会调用getTask,尝试从workQueue获取Runnable
    }
    else if (!addWorker(command, false)) // 尝试创建非核心线程,处理command
        reject(command);
}

addWorker()函数

addWorker函数,可以结合execute函数一起看,主要作用就是一系列的判断,初始化worker,调用worker run。

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

        // Check if queue empty only if necessary.
        // 这里负责校验runState以及workQueue,从而决定是否需要拒绝command
        // SHUTDOWN状态是不接受新任务,但是会处理排队任务
        // rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty() 表达式用于判断是否当前处于SHUTDOWN状态 并且 是否为处理排队任务
        if (rs >= SHUTDOWN &&
            ! (rs == SHUTDOWN &&
               firstTask == null &&
               ! workQueue.isEmpty()))
            return false;

        for (;;) {
            int wc = workerCountOf(c);
            if (wc >= CAPACITY ||
                wc >= (core ? corePoolSize : maximumPoolSize))
                return false; // 这里比较容易理解,wc大于等于容量,或者大于等于边界coreSize或maxSize,则拒绝command
            if (compareAndIncrementWorkerCount(c))
                break retry; // CAS操作成功,则break retry代码段。
            c = ctl.get();  // Re-read ctl
            if (runStateOf(c) != rs) // 重新校验状态,如果状态变化了,重新直接retry,否则重新执行内层for循环,继续CAS
                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); // new Worker
        final Thread t = w.thread;
        if (t != null) {
            final ReentrantLock mainLock = this.mainLock; 
            mainLock.lock(); // 尝试获取锁,当前使用的是NonfairSync
            try {
                // Recheck while holding lock.
                // Back out on ThreadFactory failure or if
                // shut down before lock acquired.
                // 在获取锁之后,需要重新检查
                // 如果在获得锁之前,runState 变化了,或者线程工厂失败了,需要退出
                int rs = runStateOf(ctl.get());

                // 所有状态都OK,处理成员变量和标志位逻辑
                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(); // 运行线程,最终调用runWorker
                workerStarted = true;
            }
        }
    } finally {
        // 如果添加不成功,则调用addWorkerFailed
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;
}

runWorker()函数

核心函数 -- 由worker类的run()函数调用

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true; // 标志worker是否异常结束
    try {
        while (task != null || (task = getTask()) != null) {
            w.lock();
            // 以下判断是否需要interrupt worker
            // 判断线程池状态
            // 再次判断线程和线程池状态,因可能调用了shutdownnow
            // 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())
                wt.interrupt();
            try {
                beforeExecute(wt, task);
                Throwable thrown = null;
                try {
                    task.run();
                } catch (RuntimeException x) {
                    thrown = x; throw x;
                } catch (Error x) {
                    thrown = x; throw x;
                } catch (Throwable x) {
                    thrown = x; throw new Error(x);
                } finally {
                    afterExecute(task, thrown);
                }
            } 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();
        int rs = runStateOf(c);

        // Check if queue empty only if necessary.
        // 线程池状态(状态参照前文),减少worker数量
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }

        int wc = workerCountOf(c);

        // Are workers subject to culling?
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
        // 核心线程在getTask永驻,始终等待task
        // 非核心线程,在这里返回null之后,结束
        // allowCoreThreadTimeOut 如果为true,则核心线程也会timeout,结束
        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            // 减少worker数量,并返回null
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
            // poll等待keepAliveTime,或直接take
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : // 等待keepAliveTime
                workQueue.take();
            // 获取到runnable则返回,否则设置timeOut为true
            if (r != null)
                return r;
            timedOut = true; // time out
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

processWorkerExit

private void processWorkerExit(Worker w, boolean completedAbruptly) {
    // 如果是异常结束的,则减少worker数量,正常结束会在getTask函数中做CAS
    if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        decrementWorkerCount();

    // 统计总计完成的task数量
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        completedTaskCount += w.completedTasks;
        workers.remove(w);
    } finally {
        mainLock.unlock();
    }

    // 判断线程池状态,是否需要中断worker,以及结束线程池
    tryTerminate();

    // 若当前线程池的状态是RUNNING或SHUTDOWN时,
    // 至少保证线程池里有1个或者corePoolSize个线程存在。
    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
        }
        addWorker(null, false);
    }
}

Worker类

private final class Worker
    extends AbstractQueuedSynchronizer
    implements Runnable
{
    /**
     * This class will never be serialized, but we provide a
     * serialVersionUID to suppress a javac warning.
     */
    private static final long serialVersionUID = 6138294804551838833L;

    /** Thread this worker is running in.  Null if factory fails. */
    final Thread thread;
    /** Initial task to run.  Possibly null. */
    Runnable firstTask;
    /** Per-thread task counter */
    volatile long completedTasks;

    /**
     * Creates with given first task and thread from ThreadFactory.
     * @param firstTask the first task (null if none)
     */
    Worker(Runnable firstTask) {
        setState(-1); // inhibit interrupts until runWorker
        this.firstTask = firstTask;
        this.thread = getThreadFactory().newThread(this);
    }

    /** Delegates main run loop to outer runWorker. */
    public void run() {
        runWorker(this);
    }

    // Lock methods
    //
    // The value 0 represents the unlocked state.
    // The value 1 represents the locked state.

    protected boolean isHeldExclusively() {
        return getState() != 0;
    }

    protected boolean tryAcquire(int unused) {
        if (compareAndSetState(0, 1)) {
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

    protected boolean tryRelease(int unused) {
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }

    public void lock()        { acquire(1); }
    public boolean tryLock()  { return tryAcquire(1); }
    public void unlock()      { release(1); }
    public boolean isLocked() { return isHeldExclusively(); }

    void interruptIfStarted() {
        Thread t;
        if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
            try {
                t.interrupt();
            } catch (SecurityException ignore) {
            }
        }
    }
}

 

你可能感兴趣的:(Android)