线程池ThreadPoolExecutor源码分析

本期带大家来分析线程池ThreadPoolExecutor的源码,在看本文之前最好要知道线程池的执行逻辑和核心参数,这样更方便从源码入手分析流程。

重要的属性

//高3位表示线程池运行状态,除去高3位后的低位,表示当前线程池中线程的数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

//表示在ctl中存放线程数量的位数
private static final int COUNT_BITS = Integer.SIZE - 3;

//线程的最大个数 00011111111111111111111111111111
private static final int CAPACITY   = (1 << COUNT_BITS) -1;

//以下是线程池的运行状态
//11100000000000000000000000000000  是一个负数
private static final int RUNNING    = -1 << COUNT_BITS;

//00000000000000000000000000000000
private static final int SHUTDOWN   =  0 << COUNT_BITS;

//00100000000000000000000000000000
private static final int STOP       =  1 << COUNT_BITS;

//01000000000000000000000000000000
private static final int TIDYING    =  2 << COUNT_BITS;

//01100000000000000000000000000000
private static final int TERMINATED =  3 << COUNT_BITS;

//任务队列,当线程池的线程数达到核心线程数时,再提交任务就会提交到该队列中
private final BlockingQueue<Runnable> workQueue;

//线程池全局锁,增加worker 减少 worker 时需要持有mainLock , 修改线程池运行状态时,也需要。
private final ReentrantLock mainLock = new ReentrantLock();

//线程池,存放线程的集合
private final HashSet<Worker> workers = new HashSet<Worker>();

//当外部线程调用awaitTermination()方法时,外部线程需要等待线程池状态为TERMINATED,否则加入条件队列
private final Condition termination = mainLock.newCondition();

//记录线程池生命周期内最大线程数
private int largestPoolSize;

//记录线程池所完成的任务总数,当worker退出时会将worker完成的任务累计到该字段上
private long completedTaskCount;

//线程工厂
private volatile ThreadFactory threadFactory;

//拒绝策略
private volatile RejectedExecutionHandler handler;

//核心线程数内的线程是否可以被回收。true 可以,false不可以。
private volatile boolean allowCoreThreadTimeOut;

//空闲线程存活时间,当allowCoreThreadTimeOut == false 时,会维护核心线程数量内的线程存活,超出部分会被超时。
//allowCoreThreadTimeOut == true 核心数量内的线程空闲时也会被回收。
private volatile long keepAliveTime;

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

//最大线程数
private volatile int maximumPoolSize;

//默认的拒绝策略
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();

在这里还需要提前知道线程池每一种状态下都能能做什么。

从整型值来看RUNNING < SHUTDOWN < STOP < TIDYING < TERMINATED。

RUNNING:线程池初始化状态,这时线程池可以接收新任务的提交

SHUTDOWN:调用shutdown()方法时,线程池由RUNNING变为SHUTDOWN,这时不能接收新任务,但能继续处理已添加的任务。

STOP:调用shutdownNow()方法时,由RUNNING或SHUTDOWN变为STOP,这时不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。

TIDYING:当线程池ctl记录的线程数为0时,线程池会变为TIDYING。在SHUTDOWN状态下,任务队列为空并且线程池为空,会由SHUTDOWN变为TIDYING。在STOP状态下,线程池为空,就会由STOP变为TIDYING。

TERMINATED:线程池生命周期结束。在TIDYING状态下,执行完terminated()方法后,会变为TERMINATED。

所以线程池在RUNNING和SHUTDOWN状态时,都是可以执行任务的。

重要的辅助方法

//获取当前线程池运行状态
//CAPACITY: 00011111111111111111111111111111
//~CAPACITY:11100000000000000000000000000000
//这时再回到上面看看线程池状态的值,只有高3位才有1,所以&可以计算出线程池状态
private static int runStateOf(int c)     { return c & ~CAPACITY; }

//获取当前线程池线程数量,计算同上
private static int workerCountOf(int c)  { return c & CAPACITY; }

//计算ctl的值,rs是线程池状态,wc是线程数
//rs只有高3位里面才可能包含1  wc除了高3位里面才可能包含1
private static int ctlOf(int rs, int wc) { return rs | wc; }

//c:ctl  s:线程池某个状态
//比较当前线程池状态,是否小于某个状态
private static boolean runStateLessThan(int c, int s) {
    return c < s;
}

//比较当前线程池状态,是否大于等于某个状态
private static boolean runStateAtLeast(int c, int s) {
    return c >= s;
}

//是否是RUNNING, SHUTDOWN==0  RUNNING为负数
private static boolean isRunning(int c) {
    return c < SHUTDOWN;
}

//cas 将ctl加1,表示线程数加1
private boolean compareAndIncrementWorkerCount(int expect) {
    return ctl.compareAndSet(expect, expect + 1);
}

//cas 将ctl减1,表示线程数减1
private boolean compareAndDecrementWorkerCount(int expect) {
    return ctl.compareAndSet(expect, expect - 1);
}

//让ctl减1
private void decrementWorkerCount() {
   //这里会一直重试,直到成功为止。
   do {} while (! compareAndDecrementWorkerCount(ctl.get()));
}

内部类Worker

在ThreadPoolExecutor内还有个最重要的内部类Worker,还记得前面存储线程的集合HashSet吗?存储的类型就是Worker

//Worker继承了AQS实现了独占模式,在前面分析ReentrantLock的时候已经分析过了
private final class Worker extends AbstractQueuedSynchronizer implements Runnable{

    //Worker内持有的线程
    final Thread thread;
    //第一个任务,Worker启动后会优先执行firstTask,执行完后才会去任务队列取任务
    Runnable firstTask;
    //当前Worker完成的所有任务数量
    volatile long completedTasks;
    
    //firstTask可以为null
    Worker(Runnable firstTask) {
        //设置AQS锁状态
        setState(-1);
        this.firstTask = firstTask;
        //使用线程工厂创建线程,并将当前Worker实例做为Runnable传入
        this.thread = getThreadFactory().newThread(this);
    }
    
    //由于在构造方法内创建线程时,将自身做为了Runnable,所以线程会回调这个run()
    public void run() {
        //外部类,也就是ThreadPoolExecutor的方法
        runWorker(this);
    }
    
    //以下是AQS相关方法,不多介绍
    //是否被独占
    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(); }
}

到这里有关线程池的重要前提就分析完毕,我们实际使用线程池的时候通常是用execute()或submit()提交任务,我们从这两个方法开始入手。

submit()提交任务

线程池的submit()方法是在#AbstractExecutorService中,有3个重载方法

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    //还是调用execute()
    execute(ftask);
    return ftask;
}

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

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}

protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    return new FutureTask<T>(callable);
}

但不管是哪一个,都是将Runnable或Callable封装成FutureTask由execute()进行提交任务,所以重点在execute()方法内。

execute()提交任务

#ThreadPoolExecutor
public void execute(Runnable command) {
    //非空判断
    if (command == null)
        throw new NullPointerException();
    //获取ctl的值,高3位表示线程池状态,低29位表示当前线程池内线程数量
    int c = ctl.get();
    //workerCountOf() 获取当前线程数量
    //如果小于核心线程数
    if (workerCountOf(c) < corePoolSize) {
        //addWorker()创建worker对象,将command作为firstTask
        if (addWorker(command, true))
            //创建成功会返回
            return;
        //执行到这,说明创建失败了
        c = ctl.get();
    }
    //执行到这,几种情况?
    //1.线程数>=核心线程数
    //2.addWorker()创建失败
    
    //isRunning()判断线程池是否是运行态
    //workQueue.offer()向任务队列提交任务
    if (isRunning(c) && workQueue.offer(command)) {
        //执行到这,说明是运行态并且提交任务队列成功
        //recheck保存ctl的最新值
        int recheck = ctl.get();
        //remove() 删除任务
        if (!isRunning(recheck) && remove(command))
            //如果执行到这,说明任务刚提交到队列后,线程池状态已经发生改变,不是Running
            //并且在任务队列里删除了任务
            //执行拒绝策略
            reject(command);
        
        //如果当前线程数为0
        else if (workerCountOf(recheck) == 0)
            //执行到这,说明线程池状态是Running,但是内部没有线程了
            //创建一个Worker
            //因为刚刚将任务添加到任务队列里,所以创建Worker传的任务是null
            addWorker(null, false);
    }
    
    //执行到这是什么情况?
    //1.线程池不是Running
    //2.任务队列添加失败
    //继续创建Worker,在addWorker内部会去判断线程数是否达到最大线程数
    else if (!addWorker(command, false))
        //拒绝策略
        reject(command);
}

从execute()方法内就可以看出线程池是优先创建线程达到核心线程数,再去提交任务队列的,还有最大线程数的作用没有看到,这个逻辑会在addWorker内出现。

接下来我们重点分析addWorker的过程

addWorker()

//firstTask:提交的任务
//core:是否为核心线程数
private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    //自旋,判断当前线程池是否允许创建线程
    for (;;) {
        //获取ctl
        int c = ctl.get();
        //获取线程池的状态
        int rs = runStateOf(c);
        //rs>=SHUTDOWN:说明不是Running
        //!(rs == SHUTDOWN && firstTask == null && !workQueue.isEmpty()) 注意取反了
        //这三个条件只要任意一个为false,第二个条件整体来看就为true
        if (rs >= SHUTDOWN && !(rs == SHUTDOWN && firstTask == null && !workQueue.isEmpty()))
            //执行到这,可能是线程池状态为STOP,TIDYING,TERMINATED之一
            //或提交任务为null
            //或任务队列为空
            return false;
        //以上的代码就是用来判断当前线程池的状态,是否允许添加线程
        
        //内部自旋,获取创建线程的机会
        for (;;) {
            //获取当前线程数量
            int wc = workerCountOf(c);
         	//判断线程数是否超过核心线程数或最大线程数
            if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize))
                //说明无法添加线程,返回false
                return false;
            //执行到这说明可以继续添加,先cas增加线程数
            if (compareAndIncrementWorkerCount(c))
                //成功,说明可以创建线程,跳出外部自旋
                break retry;
            
            //cas失败,获取最新的ctl
            c = ctl.get();
            //判断当前线程池状态是否发生过变化
            if (runStateOf(c) != rs)
                //发生了变化就回到外部自旋里,继续判断当前线程池状态是否可以创建线程
                continue retry;
        }
    }
    
    //表示创建的worker是否启动
    boolean workerStarted = false;
    //表示创建的worker是否添加到线程池
    boolean workerAdded = false;
    //worker的引用
    Worker w = null;
    try {
        //创建Worker,并将提交的任务赋值给firstTask
        w = new Worker(firstTask);
        //将Worker内部的线程引用赋值给t
        final Thread t = w.thread;
        //判断线程是否为null,主要是因为用户可能自定义线程工厂,在Worker的构造内会调用线程工厂创建线程
        //自定义线程工厂可能会有bug,返回null
        if (t != null) {
            //获取全局锁
            final ReentrantLock mainLock = this.mainLock;
            //加锁
            mainLock.lock();
            try {
                //获取线程池状态
                int rs = runStateOf(ctl.get());
                if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) {
                    //t.isAlive(),线程启动后会返回true,防止线程工厂创建线程后就调用start()
                    if (t.isAlive()) 
                        throw new IllegalThreadStateException();
                    //将worker添加到线程池
                    workers.add(w);
                    //获取线程数量
                    int s = workers.size();
                    //说明当前线程数是线程池生命周期内最高值
                    if (s > largestPoolSize)
                        //更新最高值
                        largestPoolSize = s;
                    //设置添加成功
                    workerAdded = true;
                }
            } finally {
                //解锁
                mainLock.unlock();
            }
            //判断是否添加成功
            if (workerAdded) {
                //启动线程
                t.start();
                //设置worker启动成功
                workerStarted = true;
            }
        }
    } finally {
        //worker启动失败
        if (!workerStarted)
            //进入添加失败的逻辑
            addWorkerFailed(w);
    }
    //返回创建的worker是否启动成功
    return workerStarted;
}

private void addWorkerFailed(Worker w) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        //worker不为null
        if (w != null)
            //从线程池内移除当前worker
            workers.remove(w);
        //将worker数-1
        decrementWorkerCount();
        //在shutdown()方法会讲
        tryTerminate();
    } finally {
        mainLock.unlock();
    }
}

addWorker()会在内部进行两种类型的判断,先去判断当前线程池状态是否能够添加线程,再去判断核心线程数和最大线程数的限制。当条件满足后会创建Worker,然后加锁,将当前Worker加入到线程池并启动,Worker内部的线程启动最终会回调到Worker的run()方法里。

以上就是线程池提交任务的逻辑,接下来就要去看线程启动后的执行逻辑了。

Worker的run()

线程工厂创建线程时,将Worker作为Runnable传入进去,所以线程启动后会回调到Worker的run()方法。

public void run() {
    runWorker(this);
}

//w:就是当前启动的worker
final void runWorker(Worker w) {
    //获取当前执行线程,就是worker内部的线程引用
    Thread wt = Thread.currentThread();
    //获取worker的firstTask
    Runnable task = w.firstTask;
    //将worker的firstTask置空
    w.firstTask = null;
    //这里为什么调用worker的解锁?可以再回到Worker内部看一下,其实是在tryRelease里面将state和独占线程清空
    w.unlock();
    //标识线程是否突然退出
    boolean completedAbruptly = true;
    try {
        //循环条件
        //task != null 第一次是指firstTask不为null
        //(task = getTask()) != null 从任务队列取出的任务不为null
        while (task != null || (task = getTask()) != null) {
            //加锁,其实是线程池处于shutdown时会判断当前worker的状态,根据独占锁判断worker是否空闲
            w.lock();
            
            //runStateAtLeast(ctl.get(), STOP)  线程池处于STOP,TIDYING,TERMINATION状态
            //这个if就是用来保证,线程池正在停止,就需要中断线程
            //如果没有,就要确保线程不被中断,并且要清除线程的中断标记位
            if ((runStateAtLeast(ctl.get(), STOP) ||
                 (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) 
                && !wt.isInterrupted())
                wt.interrupt();
            
            try {
                //留给子类实现的钩子方法
                beforeExecute(wt, task);
                //异常,如果在执行方法发现异常,就不为null
                Throwable thrown = null;
                try {
                    //执行task的run()方法
                    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清空
                task = null;
                //当前worker执行的任务数量++
                w.completedTasks++;
                //解锁,清空独占状态
                w.unlock();
            }
        }
        //上面的while条件不满足时,会执行到这
        //正常退出,将标识位设为false
        completedAbruptly = false;
    } finally {
        //1.正常退出 completedAbruptly==false
       	//2.异常退出 completedAbruptly==true
        processWorkerExit(w, completedAbruptly);
    }
}

接下来拆分runWorker()内部的两个方法,getTask()和processWorkerExit()

getTask()从任务队列取任务

private Runnable getTask() {
    //标识当前线程获取任务是否超时
    boolean timedOut = false; // Did the last poll() time out?
    for (;;) {
        //获取ctl的值
        int c = ctl.get();
        //获取当前线程池运行状态
        int rs = runStateOf(c);
        
        //rs >= SHUTDOWN 说明为非RUNNING状态
        //rs >= STOP 说明当前线程池最低处于STOP状态
        //workQueue.isEmpty() 任务队列为空
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            //减少worker数量
            decrementWorkerCount();
            return null;
        }
        
        //执行到这,说明
        //1.线程池是RUNNING
        //2.线程池是SHUTDOWN,但任务队列不为空
        
        //获取线程数量
        int wc = workerCountOf(c);
		// true表示当前线程允许超时,false不允许
        //allowCoreThreadTimeOut:是否允许核心线程超时
        //wc > corePoolSize:判断线程数量是否超过核心线程数
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
        
        //wc > maximumPoolSize 是否超过最大线程数  可能是外部重新设置了最大线程数的参数
        //timed && timedOut 用来判断线程获取任务是否超时
        //wc > 1 说明线程池还有其他线程,当前线程可以回收
        //workQueue.isEmpty() 任务队列为空
        if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
            //cas减少线程数,可能存在其他线程比当前线程先退出的情况
            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()线程退出

//completedAbruptly:true 异常退出 ,false 正常退出
private void processWorkerExit(Worker w, boolean completedAbruptly) {
    if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        //正常退出的话,在getTask()内部会将线程数-1,异常退出需要在这里进行调整
        decrementWorkerCount();
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        //将当前worker执行的任务数,累加到线程池的completedTaskCount
        completedTaskCount += w.completedTasks;
        //从线程池移除当前worker
        workers.remove(w);
    } finally {
        mainLock.unlock();
    }
    //尝试终止线程池,后面说
    tryTerminate();
    //获取ctl
    int c = ctl.get();
    //判断线程池状态至少为RUNNING或SHUTDOWN
    if (runStateLessThan(c, STOP)) {
        //正常退出
        if (!completedAbruptly) {
            //表示线程池能够持有的最少线程数
            int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
            //如果最少线程数为0,并且线程池内还有任务
            if (min == 0 && ! workQueue.isEmpty())
                //保证线程池内至少还有一个线程执行任务
                min = 1;
            //判断当前线程数是否>=min
            if (workerCountOf(c) >= min)
                //说明线程数已经足够,返回
                return; // replacement not needed
        }
        //执行到这几种情况?
        //1.线程异常退出,需要重新开启线程执行任务
        //2.任务队列还有任务,但线程数量不够
        //3.线程数量未达到核心线程数
        addWorker(null, false);
    }
}

以上就是线程池内线程的运行逻辑,当线程启动后,优先执行Worker的firstTask,执行完后会去任务队列取任务,取任务前会进行一些线程池状态的校验和线程池核心参数的校验,然后才返回任务给线程继续执行。直到任务队列也为空,线程就会执行退出的逻辑,退出也需要经过线程池状态和核心参数的校验,判断是否需要退出线程。如果执行任务期间发生异常,也会进入线程退出的逻辑,不过当前线程退出前会向线程池重新添加一个线程执行任务,然后再退出。

接下来该分析一下线程池结束的方法shutdown()和shutdownNow()了。

shutdown()

public void shutdown() {
    final ReentrantLock mainLock = this.mainLock;
    //加锁
    mainLock.lock();
    try {
        //不是重点
        checkShutdownAccess();
        //设置线程池状态为SHUTDOWN,内部就是自旋+cas修改,自行查看
        advanceRunState(SHUTDOWN);
        //中断空闲线程
        interruptIdleWorkers();
        //钩子方法
        onShutdown();
    } finally {
        //解锁
        mainLock.unlock();
    }
    //尝试终止线程池
    tryTerminate();
}

private void interruptIdleWorkers() {
    interruptIdleWorkers(false);
}

//onlyOne:false 中断所有线程 , true 中断所有线程
private void interruptIdleWorkers(boolean onlyOne) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        //遍历所有worker
        for (Worker w : workers) {
            //获取worker的线程
            Thread t = w.thread;
            //!t.isInterrupted()==true 说明当前线程还未中断
            //w.tryLock()==true  说明当前线程处于空闲
            if (!t.isInterrupted() && w.tryLock()) {
                try {
                    //中断当前线程
                    t.interrupt();
                } catch (SecurityException ignore) {
                } finally {
                    //释放woker独占锁
                    w.unlock();
                }
            }
            //onlyOne==true 只中断一个线程就退出
            if (onlyOne)
                break;
        }
    } finally {
        mainLock.unlock();
    }
}

final void tryTerminate() {
    //自旋
    for (;;) {
        //获取ctl
        int c = ctl.get();
        //isRunning(c)==true 当前线程池为RUNNING
        //runStateAtLeast(c, TIDYING)==true  说明当前已经有其他线程在执行TIDYING到TERMINATED状态了
        //runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty() SHUTDOWN状态并且任务队列不为空
        if (isRunning(c) ||
            runStateAtLeast(c, TIDYING) ||
            (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
            //当前线程直接返回
            return;
        
        //以上的条件都不满足
        //1.线程池状态为STOP
        //2.线程池状态为SHUTDOWN,任务队列也为空
        
        //线程数量不为0
        if (workerCountOf(c) != 0) { // Eligible to terminate
            //中断一个空闲线程
            //空闲线程会在阻塞队列的take()和poll()方法空闲
            //唤醒后的线程会在getTask()方法返回,然后执行退出逻辑的时候调用tryTerminate()
            //最终空闲线程都会在此处退出
            interruptIdleWorkers(ONLY_ONE);
            return;
        }
        //执行到这说明什么?
        //线程数量已经为0,执行到这的是最后一个退出的线程
        //因为在退出逻辑里面,是先将线程数-1的,所以最后一个线程会执行到这
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //cas修改线程池状态为TIDYING
            if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                try {
                    //钩子方法
                    terminated();
                } finally {
                    //设置状态为TERMINATED
                    ctl.set(ctlOf(TERMINATED, 0));
                    //唤醒调用了awaiTermination()的线程
                    termination.signalAll();
                }
                return;
            }
        } finally {
            mainLock.unlock();
        }
        // else retry on failed CAS
    }
}

shutdownNow()

public List<Runnable> shutdownNow() {
    //存储未处理的任务
    List<Runnable> tasks;
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        checkShutdownAccess();
        //设置线程池状态为STOP
        advanceRunState(STOP);
        //中断线程池中所有线程
        interruptWorkers();
        //获取未处理的任务,内部逻辑比较简单,自行查看
        tasks = drainQueue();
    } finally {
        mainLock.unlock();
    }
    //尝试终止线程池
    tryTerminate();
    //返回所有未处理的任务
    return tasks;
}

private void interruptWorkers() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        //遍历所有worker
        for (Worker w : workers)
            //如果worker内的Thread不是空闲就中断
            w.interruptIfStarted();
    } finally {
        mainLock.unlock();
    }
}

awaitTermination()

这个方法是由外部线程调用,当线程池变为TERMINATED的状态时会唤醒等待在此的线程。

public boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException {
    long nanos = unit.toNanos(timeout);
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (;;) {
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            if (nanos <= 0)
                return false;
            //Condition条件队列,相当于synchronized,获取锁的线程调用了wait()
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }
}

以上就是线程池核心源码的分析。难点主要是在判断线程池状态的逻辑上,要分很多种情况去考虑,不过只要明白线程池各状态分别能处理什么事情,加上理解了线程池的执行逻辑,源码也不是特别难分析的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值