ThreadPoolExecutor源码解析

概述

Core and maximum pool sizes

当有新的task通过execute方法提交。
1. 如果目前线程数 < corePoolSize,不论是否有空闲线程,这时都会创建一个新的线程来执行这个任务。
2. 如果corePoolSize < 目前线程数 < maximumPoolSize,只有当队列满了之后才会创建新线程

Creating new threads

使用ThreadFacotry来创建线程,该类有默认实现,其创建的线程都在同一个Group,并且优先级都一样

Keep-alive times

如果当前线程池中的线程数量 > corePoolSize,如果超出线程的空闲时间 > keepAliveTime,这些线程将被terminated。如果之后线程数量不够,那么还会再创建。设置allowCoreThreadTimeOut变量为true,也可以将keepAliveTime作用到core threads上。

Queuing

阻塞队列可以用来转移或接收task。
1. 如果目前线程 < corePoolSize,那么线程池会增加线程,而不是将task放入队列。
2. 如果当前线程 >= corePoolSize,那么线程池会将task放入队列,而不是增加线程。
3. 新task无法再加入队列(队列满了),如果目前线程 < maximumPoolSize,则会新增线程;否则会拒绝该task。

对于队列,一般有如下3中策略:
1. Direct handoffs(直接获取):这种策略适合使用SynchronousQueue,当有task来的适合,就会有线程立马处理;如果此时没有空闲线程,那么就会fail,于是会创建一个新的线程来处理这个task。这种策略的好处是,能避免因为任务间的依赖而造成线程处理的停顿。这种策略一般来说需要一个无界队列来防止task被拒绝,但是如果task来的比处理快时,队列会一致增大。
2. Unbounded queues(无界队列):一般采用LinkedBlockingQueue作为无界队列。当core thread都忙碌时,task会被放入队列,因为队列时无界的,因此线程数量不会超过corePoolSize。这种策略适合任务之间是无关的情况,如果页面请求。
3. Bounded queues(有界队列):一般采用ArrayBlockingQueue作为有界队列,它能防止task饿死,当队列满了之后,会创建新线程(当然数量不能超过maximumPoolSize)。当队列很大,但是maximumPoolSize较小的适合,CPU与资源使用率会较低,线程切换次数会增加,吞吐量会降低。当队列较小,maximumPoolSize较大时,CPU使用率会提高,但是新的task可能会被reject,因此也会降低吞吐量。

Rejected tasks

当1、线程池被关闭。2、队列满了,线程数量达到最大,由没有空闲线程的时候,新的任务会被rejected,此时会调用RejectedExecutionHandler,默认给出了4中策略:
1. ThreadPoolExecutor.AbortPolicy:当被reject时,抛出RejectedExecutionException。
2. ThreadPoolExecutor.CallerRunsPolicy:当被reject后,当前线程本身来执行之歌任务,不用线程池。
3. ThreadPoolExecutor.DiscardPolicy:直接丢弃。
4. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列中的队首任务,然后重试。

Hook methods

提供了beforeExecute以及afterExecute方法,它们分别在执行execute方法的前后执行。

源码

主要属性

public class ThreadPoolExecutor extends AbstractExecutorService {

    /*
     *  RUNNING -> SHUTDOWN,通过执行shutdown()
     *  (RUNNING or SHUTDOWN) -> STOP,通过执行shutdownNow()
     *  SHUTDOWN -> TIDYING,当队列与线程池都为空
     *  STOP -> TIDYING,当线程池为空
     *  TIDYING -> TERMINATED,当terminated()执行结束
     */
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

    // 控制偏移量,头上3为控制状态
    private static final int COUNT_BITS = Integer.SIZE - 3;

    // 线程池的最大容量为2^29-1
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // 接收新task,处理队列中的task
    private static final int RUNNING    = -1 << COUNT_BITS;

    // 不接受新的task,但是处理队列中的task
    private static final int SHUTDOWN   =  0 << COUNT_BITS;

    // 不接受task,也不处理新的task
    private static final int STOP       =  1 << COUNT_BITS;

    // 所有task都terminated,workerCount=0,执行terminated()方法
    private static final int TIDYING    =  2 << COUNT_BITS;

    // terminated()已经完成
    private static final int TERMINATED =  3 << COUNT_BITS;

    // 表明线程是running、shuting down等状态
    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; }

    // 用于保存task,通过isEmpty()方法来判断队列是否为空
    private final BlockingQueue<Runnable> workQueue;

    // 当访问worker线程集时加锁
    private final ReentrantLock mainLock = new ReentrantLock();

    // 线程池中所有的worker threads,必须要获取mainLock才能访问这个集合
    private final HashSet<Worker> workers = new HashSet<Worker>();

    private final Condition termination = mainLock.newCondition();

    // 线程池达到过的最大容量,必须要获取mainLock才能修改
    private int largestPoolSize;

    // 记录已经完成的任务数量,也要获取mainLock
    private long completedTaskCount;

    // 线程工程,用来new thread
    private volatile ThreadFactory threadFactory;

    // RejectedExecutionHandler,当task被reject时,执行这个handler
    private volatile RejectedExecutionHandler handler;

    // 非core thread保活时间
    private volatile long keepAliveTime;

    // core thread的保活时间
    private volatile boolean allowCoreThreadTimeOut;

    // 核心线程数量
    private volatile int corePoolSize;

    // 线程池可创建线程上限
    private volatile int maximumPoolSize;

    // 默认RejectedExecutionHandler
    private static final RejectedExecutionHandler defaultHandler =
        new AbortPolicy();
}

Worker源码

private final class Worker extends AbstractQueuedSynchronizer implements Runnable{

    // 当前worker running的线程
    final Thread thread;

    // 要运行的任务
    Runnable firstTask;

    // 记录当前worker完成的task数量
    volatile long completedTasks;

    // 每次创建一个worker,都会新创建一个线程。
    // 注意,这里初始化会把state设置为-1。当调用run,执行runWorker时,执行一步w.unlock();
    // tryAcquire时对state进行cas(0,1),即只要state不是0,都是加锁状态。
    Worker(Runnable firstTask) {
        setState(-1); // inhibit interrupts until runWorker
        this.firstTask = firstTask;
        this.thread = getThreadFactory().newThread(this);
    }

    // run方法调用runWorker方法
    public void run() {
        runWorker(this);
    }

}

ThreadPoolExecutor源码

先看runWorker方法。
这个方法是执行task的主要方法,会反复地从队列中获取task并执行。

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();

    // 刚开始获取worker创建时初始化的firstTask
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // 将w的state从-1变成0,即释放锁,允许中断
    boolean completedAbruptly = true;
    try {
        // 使用 || 运算,首次循环不会执行getTask(),之后会执行getTask()
        while (task != null || (task = getTask()) != null) {
            w.lock();
            // 如果线程池时stopping状态,确保线程是中断的。
            // 如果不是stopping状态,确保线程不是中断
            // 采用双重检查来应对清楚中断过程中发生二次中断。Thread.interrupted()方法会重置中断
            if ((runStateAtLeast(ctl.get(), STOP) ||
                 (Thread.interrupted() &&
                  runStateAtLeast(ctl.get(), STOP))) &&
                !wt.isInterrupted())
                wt.interrupt();
            try {
                // beforeExecute方法是Hook method,如果有需要可以重写。
                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方法是Hook method,如果有需要可以重写。
                    afterExecute(task, thrown);
                }
            } finally {
                // 让task=null,从而调用个while的getTask方法
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

getTask方法

以阻塞或time wait的形式来获取任务。

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

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

        // rs >= SHUTDOWN,那么可能是SHUTDOWN、STOP、TIDYING、TERMINATED等状态,这些状态都不接受task
        // 
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            // 使用cas的方式将workerCount-1
            decrementWorkerCount();
            return null;
        }

        // 当前线程数量
        int wc = workerCountOf(c);

        // core thread是否有timeout 或 当前线程数量有没有超过corePoolSize
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

        // 如果当前线程数量 > maximumPoolSize 或 超时了,那么就将当前worker干掉。
        // 返回null,当前线程就会退出,详见runWorker的while循环
        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
            // 如果timed=ture,那么获取任务的时候,使用poll方法,如果在规定时间内没有任务,就会返回null
            // 否则,会一直等带任务。
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

processWorkerExit方法

当worker线程被回收前执行,主要是做最后的清理工作

private void processWorkerExit(Worker w, boolean completedAbruptly) {
    // 如果completedAbruptly为true,那就代表当前线程发生了异常,推测基本是因为interupt。从而补上原本
    // 应该在getTask方法中的decrementWorkerCount。
    if (completedAbruptly)
        decrementWorkerCount();

    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        // 统计w Worker完成的任务数量,并将它从workers队列中移除
        completedTaskCount += w.completedTasks;
        workers.remove(w);
    } finally {
        mainLock.unlock();
    }

    tryTerminate();

    int c = ctl.get();
    // 如果线程池还是running状态,那么当前线程可能是因为task的异常,那么再通过addWorker方法,加一个线程进去
    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);
    }
}

addWorker增加一个worker。

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

        // 如果线程池的state不是running,或这shutdown的时候work队列为空,即没任务,那此时也不需要创建线程。
        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;
            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()) // 预检查一次,如果此时新创建的线程已经start,说明有问题。
                        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)
            // 如果workerStarted=false,回滚。回滚就是吧w从wokers中移除,并且将workerCount-1
            addWorkerFailed(w);
    }
    return workerStarted;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值