ThreadPoolExecutor源码解析

基本概念

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。

继承关系

ThreadPoolExecutor继承了AbstractExecutorService,AbstractExecutorService继承了ExecutorService,ExecutorService继承了Executor。

public interface Executor {
    // 在将来的某个时间,执行给定的command. 可能在新线程中,在线程池中,或者在一个正在被调用的线程中。
    void execute(Runnable command);
}
// 提供了一个对提交的command执行过程的管理。可以对一个或者多个task终止或者追踪执行的过程。
public interface ExecutorService extends Executor {
    // 关闭ExecutorService,关闭之前已经提交的task会执行完成,关闭之后不再接受新的task。
    void shutdown();
    // 尝试着关闭所有正在执行的task,终止正在等待的task,并返回所有正在等待task的list。
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    // Block住线程(调用awaitTermination方法的线程),直到所有task都结束,或者timeout发生,或者发生中断。
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

核心源码解析

当我们提交一个task时候,会首先将task包装成一个RunnableFuture对象ftask,然后将这个ftas将交给ThreadPoolExecutor.execute方法进行执行。

如何提交一个task是由AbstractExecutorService实现的,而如何执行这个task是ThreadPoolExecutor实现的。

// AbstractExecutorService
public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);// 将这个ftas将交给ThreadPoolExecutor.execute方法进行执行
    return ftask;
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    return new FutureTask<T>(callable);
}

ctl是用来表示ThreadPoolExecutor状态的变量。

因为Integer是32位的,用高3位表示线程池的状态(runState),用低29位来表示正在运行的线程的数量(workerCount)。

runState(线程池的状态):

  • RUNNING: 线程池正在运行,可以接受新的task或者执行队列中的task
  • SHUTDOWN: 不再接受新的task但是可以执行队列中的task
  • STOP: 不再接受新的task,不再执行队列中的task,对正在执行的task进行中断
  • TIDYING: 所有的task已经终止,workerCount是0,线程转换到TIDYING状态,然后调用terminated()
  • TERMINATED: terminated()执行完成
// ThreadPoolExecutor
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int RUNNING    = -1 << COUNT_BITS;
private static final int SHUTDOWN   =  0 << COUNT_BITS;
private static final int STOP       =  1 << COUNT_BITS;
private static final int TIDYING    =  2 << COUNT_BITS;
private static final int TERMINATED =  3 << COUNT_BITS;
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
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; }
private final BlockingQueue<Runnable> workQueue;

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    int c = ctl.get();
    //1.当workerCount<corePoolSize时,会将创建一个Worker,并且将command给这个Worker执行,
    //2.如果1不满足,则尝试将command添加到workQueue中,等有空闲的Worker的时候再执行。
    //3.如果1,2都不能满足,当workerCount<maximumPoolSize时,就创造一个新的Worker执行这个command。当所有的command执行完成之后,就销毁超过corePoolSize数量的Worker。
    //4.如果以上都不满足,就拒绝添加任务,将调用其RejectedExecutionHandler的RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。
    if (workerCountOf(c) < corePoolSize) { // 如果worker的数量少于corePoolSize,就添加一个worker,并让这个worker执行command
        if (addWorker(command, true))
            return;
        c = ctl.get(); //如果addWorker方法返回false,则说明有另一个线程调用了addWorker,成功使workerCount加一,更新了ctl,并且workerCount不再小于corePoolSize。
    }
    if (isRunning(c) && workQueue.offer(command)) {//将command添加到workQueue中,添加成功返回true,否则返回false.
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
    else if (!addWorker(command, false))//当workQueue满了之后,尝试创建新的Worker来执行command。
        reject(command);//创建新的Worker失败后,调用reject。
}

通过firstTask创建一个Worker,并将创建的Worker添加到workers中,并且调用Worker内置线程的run方法,执行firstTask

// ThreadPoolExecutor
private final HashSet<Worker> workers = new HashSet<Worker>();
private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);

        // 当ThreadPoolExecutor被shutdown方法之后,不再接受task.
        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)) //尝试着给workerCount加一
                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); //声明一个Worker,在创建Worker的时候,会使用ThreadFactory创建一个线程并内置在Worker中。因为Worker继承了Runnable,所以当创建Worker内置线程时,将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); //将w添加到workers中
                    int s = workers.size();
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                t.start();//启动Worker内置的线程
                workerStarted = true;
            }
        }
    } finally {
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;
}

Worker继承了AbstractQueuedSynchronizer(AQS)用来保证,每次Worker只能执行一个task, 执行完才能执行下一个。

当Worker执行task的时候,首先从Worker.firstTaskh或者getTask()获取一个task,然后获取锁为了保证一个worker中的threads在执行过程中不能被中断,然后调用task.run()

//Worker
Worker(Runnable firstTask) {
    setState(-1); // inhibit interrupts until runWorker
    this.firstTask = firstTask;
    this.thread = getThreadFactory().newThread(this);
}

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

//ThreadPoolExecutor
final void runWorker(Worker w) {
    Thread wt = Thread.currentThread(); //上面通过ThreadFactory创建的新线程
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
        while (task != null || (task = getTask()) != null) { //从workQueue中获取task
            w.lock(); //这里的lock是为了保证一个worker中的threadz在执行过程中不能被中断。
            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();//执行这个task
                } 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();//执行完成后,释放锁,使worker可以被中断。
            }
        }
        completedAbruptly = false;
    } finally {
        //处理抛出exception的线程,或者取道task==null的线程
        processWorkerExit(w, completedAbruptly);
    }
}

当有线程由于exception发生错误的时候,会将发生错误的Worker从workers中删除,

然后根据线程池中corePoolSize和存活的Worker的数量来决定是否添加新的Worker

//ThreadPoolExecutor
private void processWorkerExit(Worker w, boolean completedAbruptly) {
    if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        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) //当worker的数量多于corePoolSize的时候,不再添加新的线程代替刚才被移出的线程。
                return; // replacement not needed
        }
        addWorker(null, false);//添加新的线程
    }
}

当从workQueue中取task时,如果workerCount > corePoolSize, 说明运行的worker多于corePoolSize,将采用workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)的方式去取task。

当workQueue中有task时,就可以顺利取出,否则在keepAliveTime时间之后还没有task就会返回null.

如果workerCount <= corePoolSize,使用可以阻塞的workQueue.take()取task。

private Runnable getTask() {
    boolean timedOut = false;
    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);

        // Check if queue empty only if necessary.
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }
        int wc = workerCountOf(c);
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            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;
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值