ThreadPoolExecutor源码分析

原创 2018年04月16日 10:52:52

ThreadPoolExecutor继承AbstractExecutorService,层级实现了ExecutorService,ExecutorService继承了Executor

1 . Executor
Executor提供了一种解耦任务提交与任务如何运行的 execute(Runnable command)方法,例如创建线程并启动是这样的:

new Thread(()->{}).start();

而使用execute(Runnable command) 方法后:

Executor executor = anExecutor;
executor.execute(new Runnable(()->{}));
class MyExecutor implements Executor{
    public void execute(Runnable command){
        new Thread(command).start();    
    }
}

2 . ExecutorService
ExecutorService提供了管理终结,并且生成追踪一个或多个异步任务的Future的方法。

package java.util.concurrent;
import java.util.List;
import java.util.Collection;
public interface ExecutorService extends Executor {
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    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;
}

Future提供了取消任务,以及获取任务的执行状态等方法。例如:

ExecutorService service = anExecutorService;
Future future = service.submit(new Runnable(()->{}));
future.cancel();
future.isDone();

3 . AbstractExecutorService
AbstractExectorService则是提供了ExectorService的默认实现,这里不详细描述了
4 . ThreadPoolExecutor
字段分析:
ctl 的高位存储线程的运行状态,低位存储工作线程的数量,可见线程刚创建时线程状态为运行状态,工作线程数为0
COUNT_BITS用于决定线程状态移动的位数
CAPACITY用于计算线程运行状态与工作线程数量

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // 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;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;
    private final BlockingQueue<Runnable> workQueue;//阻塞队列
    private final ReentrantLock mainLock = new ReentrantLock(); //可重入锁
    private final HashSet<Worker> workers = new HashSet<Worker>(); //用来存放工作线程的Set集合
    private final Condition termination = mainLock.newCondition();
    private int largestPoolSize; // 用来记录线程池最大时候的大小(线程池监控)
    private long completedTaskCount; // 任务完成的数量(线程池监控)
    private volatile ThreadFactory threadFactory; // 顾名思义线程创建工厂,线程池在创建线程时会调用它的newThread(Runnable r)方法
    private volatile RejectedExecutionHandler handler; // 当线程池达到最大容量时的处理方法 默认AbortPolicy
    private volatile long keepAliveTime; //超出corePoolSize的线程会在空闲keepAliveTime后被销毁
    private volatile boolean allowCoreThreadTimeOut; //当为true时,核心线程也会被销毁
    private volatile int corePoolSize;// 核心线程池大小
    private volatile int maximumPoolSize;// 线程池最大容量
    private static final RejectedExecutionHandler defaultHandler =
        new AbortPolicy();  

核心方法分析:
先从最最最常用的execute(Runnable command)方法讲起,但是在讲之前呢,还要先了解一下addWorker(Runnable firstTask,Boolean core)方法:

 private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);// 计算线程池运行状态
            // 如果线程池不为RUNNING状且者线程池为SHUTDOWN状态firstTask为空,或工作队列为空时返回false
            //意思就是,当线程处于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;
                // cas增加工作线程数量 成功则退出整个循环
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // cas失败,如果运行状态改变,则自循环
                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构造方法会调用ThreadFactory来构造Thread
            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();
                        //J将worker加入集合
                        workers.add(w);
                        int s = workers.size();
                        //记录线程池的最大数量
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                //如果添加成功 则启动线程
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
                //如果线程不能启动,则将worker从集合中移除
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }
public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();

        int c = ctl.get();
        // 如果工作线程数量小于核心线程池大小
        if (workerCountOf(c) < corePoolSize) {
            //那么就创建一个工作线程来完成任务
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        // 否则 如果是运行状态,那么尝试将任务添加进任务队列
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            //再次检查线程状态,如果不是运行状态,则将任务从任务队列移除
            if (! isRunning(recheck) && remove(command))
                //并用构造构造线程池时的RejectedExecutionHandlerL来处理 也就是说当线程状态不为RUNNING时,将会拒绝新的任务
                reject(command);
            else if (workerCountOf(recheck) == 0)
            //如果当前没有工作线程,那么创建一个工作线程来执行工作队列中的人物
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

调用shutDown()方法,不会立即终结线程池,而是不再接受新的任务,如果任务队列中还有任务,会等待任务执行完毕。

 public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 检查权限
            checkShutdownAccess();
            // 自旋锁 cas来改变线程的状态为SHUTDOWN
            advanceRunState(SHUTDOWN);
            // 终止空闲的工作线程 
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        // 尝试终结线程池
        tryTerminate();
    }

而shutDownNow()方法则为

public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 检查权限
            checkShutdownAccess();
            // 自旋锁 cas将线程状态置为STOP状态
            advanceRunState(STOP);
            // 每个工作线程都会调用interrupt()方法
            interruptWorkers();
            // 将工作队列中任务全部移除,不再执行
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        // 尝试终结线程
        tryTerminate();
        // 返回工作队列的List集合
        return tasks;
    }

shutDown()与shutDownNow的最大区别就是shutDown()只会为空闲的worker调用interrupt()方法,而shutDownNow()则会为每一个worker调用interrupt()方法,shutDown()会将工作队列中的现有任务执行完毕,再终结,而shutDownNow()会将工作队列中的任务都移除。

如有错误,欢迎指正

基于jdk1.8的ThreadPoolExecutor源码分析

比较详细的线程池源码分析。
  • u011801264
  • u011801264
  • 2016-08-29 10:33:18
  • 228

Java 1.7 ThreadPoolExecutor源码解析

相比1.6,1.7有些变化: 1、        增加了一个TIDYING状态,这个状态是介于STOP和TERMINATED之间的,如果执行完terminated钩子函数后状态就变成TERMINAT...
  • yuenkin
  • yuenkin
  • 2016-04-01 23:04:43
  • 1699

聊聊高并发(四十)解析java.util.concurrent各个组件(十六) ThreadPoolExecutor源码分析

ThreadPoolExecutor是Executor执行框架最重要的一个实现类,提供了线程池管理和任务管理是两个最基本的能力。这篇通过分析ThreadPoolExecutor的源码来看看如何设计和实...
  • ITer_ZC
  • ITer_ZC
  • 2015-07-16 16:27:08
  • 3329

Java ThreadPoolExecutor线程池原理及源码分析

一、源码分析(基于JDK1.6) ThreadExecutorPool是使用最多的线程池组件,了解它的原始资料最好是从从设计者(Doug Lea)的口中知道它的来龙去脉。在Jdk1.6中,Threa...
  • scherrer
  • scherrer
  • 2016-02-21 17:27:01
  • 1326

Android之ThreadPoolExecutor源码分析

ThreadPoolExecutor是一个有固定核心线程数的线程池,下面根据源码来详细介绍一下ThreadPoolExecutor的设计和思想首先看一下ThreadPoolExecutor的类图首先了...
  • android_Text
  • android_Text
  • 2017-04-21 15:31:52
  • 333

ThreadPoolExecutor解析-主要源码研究

ThreadPoolExecutor解析-主要源码研究
  • wenhuayuzhihui
  • wenhuayuzhihui
  • 2016-05-26 14:26:24
  • 7590

Java 线程池 ThreadPoolExecutor 源码分析

线程池能够对线程进行有效的管理, 复用和数量上限的限制, 所以比起原始的 new Thread().start() 这种创建并启动线程的方式, 线程池的效率和性能都更好. Java 中的线程池是用 ...
  • cleverGump
  • cleverGump
  • 2016-02-18 18:51:33
  • 5320

java并发编程之源码分析ThreadPoolExecutor线程池实现原理

本文从线程池的创建、核心线程数、最大线程数、线程的创建、任务队列、拒绝策略、工作线程keep-alive等方面详细解读了线程池特性。然后介绍了线程池的状态以及线程池的实现原理,详解了addWorker...
  • prestigeding
  • prestigeding
  • 2016-12-29 16:25:37
  • 2314

JDK1.8源码分析之ThreadPoolExecutor

一、前言   JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:...
  • qq_22929803
  • qq_22929803
  • 2016-08-28 19:52:54
  • 2093

ThreadPoolExecutor源码分析(一):重要成员变量

ThreadPoolExecutor是一个通过使用可能几个池线程之一来执行每个提交任务的ExecutorService,这些线程池通常通过Executors工厂方法进行配置。 Thre...
  • lipeng_bigdata
  • lipeng_bigdata
  • 2016-04-24 14:51:24
  • 3928
收藏助手
不良信息举报
您举报文章:ThreadPoolExecutor源码分析
举报原因:
原因补充:

(最多只允许输入30个字)