Executor框架(四) — ThreadPoolExecutor源码解析

一、概述

版本: JDK1.8

文章链接如下:

  1. Executor框架(一) — 综述
  2. Executor框架(二) — 线程池原理浅析
  3. Executor框架(三) — 几种常见的线程池

在上面两篇文章中,我们分析了 ThreadPoolExecutor 的实现原理和通过 ThreadPoolExecutor 实现的几种具有不同特点的线程池。下面我们就分析一下 ThreadPoolExecutor 具体的实现。

二、ThreadPoolExecutor 执行任务示意图

在这里插入图片描述

三、ThreadPoolExecutor 源码分析

主要分析以下几部分:

  1. 构造参数的含义;
  2. 常量的意义;
  3. 提交任务的方法;
    1. execute() 不带返回值
    2. submit() 带返回值
  4. addWorker(Runnable firstTask, boolean core) 方法
  5. Worker
    1. runWorker() 方法

1. 构造参数的含义

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
     // do something
}

参数含义参考文章:Executor框架(二) — 线程池原理浅析


2. 常量

/**
 * 一个同时记录线程池状态和线程个数的变量。
 * @desc: Integer 的位数为 32 位,其中高 3 位表示线程池的状态,低 29 位表示线程的个数。
 * 		默认为 RUNNING 状态,线程个数为 0。
 */
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; //29
/**
 * 1<<29 = 00100000 00000000 00000000 00000000
 * (1<<29) - 1 = 00011111 11111111 11111111 11111111
 * ~CAPACITY(取反) = 11100000 00000000 00000000 00000000
 */
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

// runState: 高3位代表线程池的状态; 低29位代表线程的数量(线程数最多为(2^29)-1 )
private static final int RUNNING    = -1 << COUNT_BITS; //11100000 00000000 00000000 00000000
private static final int SHUTDOWN   = 0 << COUNT_BITS; //00000000 00000000 00000000 00000000
private static final int STOP       = 1 << COUNT_BITS; //00100000 00000000 00000000 00000000
private static final int TIDYING    = 2 << COUNT_BITS; //01000000 00000000 00000000 00000000
private static final int TERMINATED = 3 << COUNT_BITS; //01100000 00000000 00000000 00000000

// Packing and unpacking ctl
// 通过取反(获得前三个高位全为1),然后和传入的c进行&运算,可判断出线程池目前是什么状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
//通过与运算可以算出线程数
private static int workerCountOf(int c) { return c & CAPACITY;  }
// 计算 ct l的值,用线程池状态和线程个数进行或运算
private static int ctlOf(int rs, int wc) { return rs | wc; }

注: 如果想查看上面变量的二进制形式,可以通过方法 Integer.toBinaryString(int i) 查看。

补码的相关知识

计算机只能进行加法运算,为了处理负数的问题,引入的补码的相关概念。

  1. 一个int类型的整数占用了4个字节,共 32 bits,其中最高位的bit代表符号位(0代表正数;1代表负数),剩余 31bits 代表数字部分;数字部分都用补码来表示。

  2. 原码、反码、补码的转换规则:
    原码:数字转换为二进制后的数字;
    反码:如果是正数,则反码=原码;如果是负数,除符号位不变,其它位按照原码各位进行取反;
    补码:如果是正数,则补码=反码=原码;如果是负数,则在反码的基础上加1;

详细可参考这篇文章: 数据结构 — 原码, 反码, 补码 详解 - 第三部分

示例: private static final int RUNNING = -1 << COUNT_BITS;

COUNT_BITS = 29
-1原码:10000000,00000000,00000000,00000001 (最高位为1,代表负数)
-1反码: 11111111 , 11111111 , 11111111 , 11111110 (最高位不动,其余各位与原码取反)
-1补码: 11111111 , 11111111 , 11111111 , 11111111 (在反码的基础上加1)
-1 << 29:11100000,00000000,00000000,00000000 (补码各位整体向左移动29位,右边用0补齐位置)

runState 几种状态的说明

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. (所有任务已终止,workerCount为0,处于TIDYING状态的线程将调用钩子方法terminated())
TERMINATED:terminated() has completed. (terminated()方法完成)

runState 状态转化的过程:

RUNNING -> SHUTDOWN:On invocation of shutdown(), perhaps implicitly in finalize().
(RUNNING or SHUTDOWN) -> STOP:On invocation of shutdownNow().
SHUTDOWN -> TIDYING:When both queue and pool are empty.
STOP -> TIDYING:When pool is empty.
TIDYING -> TERMINATED:When the terminated() hook method has completed.


3. 提交任务: execute()、submit()

ThreadPoolExecutor 线程池提交任务有两种方式:

  1. 不带返回值:execute(Runnable)
  2. 带返回值:submit(Callable)submit(Runnable)

execute()

// ThreadPoolExecutor.class
public void execute(Runnable command) {
  if (command == null)
        throw new NullPointerException();
  
    // 获取表示线程池状态和线程个数的组合变量 ctl
    int c = ctl.get();
    // 如果线程个数小于核心线程数,则创建线程并执行当前任务
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }
    
    // 代码执行到这里说明:1. 线程个数>=核心线程数;2.执行 addWorder 方法失败)
    // 如果线程池处于 RUNNAING 状态,就把任务添加到阻塞队列中
    if (isRunning(c) && workQueue.offer(command)) {
        // 再次获取组合变量 ctl,做二次检查(因为线程池的状态可能已经发生了改变)
        int recheck = ctl.get();
        // 如果线程池状态不是 RNUUAING 状态,就把该任务从阻塞任务队列中移除,并执行拒绝策略
        if (! isRunning(recheck) && remove(command))
            reject(command);
        // 如果线程池中线程个数为0(则刚才的任务肯定在阻塞队列里),就新建一个线程
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
    // 代码执行到这里,说明任务无法添加进队列(队列满了),则尝试新建一个线程处理这个任务;
    // 如果线程创建失败,则说明“线程个数达到最大线程数”或者“线程池处于SHUTDOWN状态”,执行拒绝策略
    else if (!addWorker(command, false))
        reject(command);
}

submit()

submit() 接收两种参数:Runnable 不带返回值Callable 带返回值

// AbstractExecutorService.class
public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    // 构造一个FutureTask实例,作用是获得返回值
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask); //最后还是调用
    return ftask;
}

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    // 构造一个FutureTask实例,作用是获得返回值
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}

// Callable.class
public interface Callable<V> {
    V call() throws Exception;
}

4. addWorker(Runnable firstTask, boolean core) 方法

execute() 方法中可以看到,加入任务后会执行 addWorker() 方法。

// ThreadPoolExecutor.class
private boolean addWorker(Runnable firstTask, boolean core) {
	retry: //这是个跳出外层循环的标记.
	for (;;) {
		int c = ctl.get();
		int rs = runStateOf(c);
		
		// Check if queue empty only if necessary.
		// 由上面“常量”部分可知,SHUTDOWN 状态下,线程池不接收新任务,但会处理队列中的任务。
		// 条件 (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()),代表线程池处于shutdown,且 firstTask 为 null, 同时队列不为空的条件下,允许创建 worker.
		// 在线程池状态处于非 RUNNING 的状态下,只有以下一种情况((rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) 是允许创建worker线程的,其他场景都不允许。
		if (rs >= SHUTDOWN &&  // rs >= SHUTDOWN 代表rs 的状态是除 RUNNING 的所有状态
		  	! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) 
		  	return false;
	
		for (;;) { //自旋
			// 获取当前线程池的线程数
			int wc = workerCountOf(c);
			// 根据core的值来确定当前线程数是否超过线程数的边界(core ? corePoolSize : maximumPoolSize),超过了则不创建新的worker.
			if (wc >= CAPACITY ||
			     wc >= (core ? corePoolSize : maximumPoolSize))
			     // 进入这里,代表当前线程数超过了线程数的边界,所以不创建新的worker.
			     return false;
			// 通过 CAS来使工作线程数+1 (如果这里操作失败,则表示有并发操作)
			if (compareAndIncrementWorkerCount(c))
			     break retry;
			// 如果上面的CAS操作没有成功,说明存在并发操作,因此需要重新读取 ctl 值进行状态判断
			c = ctl.get();  // Re-read ctl
			// 判断当前的线程状态是否发生变化?(分两种情况:变化了、没变化)
			if (runStateOf(c) != rs) // runStateOf(c) != rs 这个判断操作主要是看当前线程池的状态变没变,
			     continue retry; // 执行到这里面,说明线程状态发生了变化,则回到外层的for循环重新执行。
            // 如果没有执行 `continue retry` 方法,说明线程状态没变,因此重新执行内层循环,重新执行CAS操作。
			// else CAS failed due to workerCount change; retry inner loop
		}
	}

	boolean workerStarted = false;
	boolean workerAdded = false;
	Worker w = null;
	try {
		// 把 task 封装成 worker。(通过线程工厂创建线程时,会把任务设置到 Thread 的 target 属性上,后续在执行线程的 start 方法时,就会执行对应的任务的 run 方法。)
	    w = new Worker(firstTask);
	    final Thread t = w.thread;
	    if (t != null) {
	        final ReentrantLock mainLock = this.mainLock;
	        // 这里会获取全局锁,所以如果频繁执行创建Worker(),会出现性能瓶颈。
	        mainLock.lock();
	        try {
	            // Recheck while holding lock.
	            // Back out on ThreadFactory failure or if
	            // shut down before lock acquired.
	            int rs = runStateOf(ctl.get());
				// 如果线程池处于 Running 状态 或者 线程池处于 shutdown 状态且 firstTask=null(执行任务队列中的任务)
	            if (rs < SHUTDOWN ||  //rs < SHUTDOWN表示线程池处于Running 状态
	                (rs == SHUTDOWN && firstTask == null)) {
	                if (t.isAlive()) // precheck that t is startable
	                    throw new IllegalThreadStateException();
	                workers.add(w);  // 将新建的 worker 添加到 worker 集合中
	                int s = workers.size(); 
	                if (s > largestPoolSize)
	                    largestPoolSize = s; // largestPoolSize 记录 workers 中个数存在过的最大值。
	                workerAdded = true; 
	            }
	        } finally {
	            mainLock.unlock();
	        }
	        if (workerAdded) {
	            t.start();  //启动线程
	            workerStarted = true;
	        }
	    }
	} finally {
	    if (! workerStarted) //如果工作线程没有启动
	        addWorkerFailed(w);  //则回滚之前的设置;
	}
	return workerStarted;
}

/**
 * Rolls back the worker thread creation.
 * - removes worker from workers, if present
 * - decrements worker count
 * - rechecks for termination, in case the existence of this worker was holding up termination
 */
private void addWorkerFailed(Worker w) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        if (w != null)
            workers.remove(w); // 1.将worker从workers中移除;
        decrementWorkerCount(); // 2.将cls中的worker数量还原;
        tryTerminate(); // 3.重新检测线程池的状态
    } finally {
        mainLock.unlock();
    }
}

5. Worker 类

// ThreadPoolExecutor.Worker.class
Worker(Runnable firstTask) {
    setState(-1); // inhibit interrupts until runWorker
    this.firstTask = firstTask;
    // 此处newThread(this) 传入的this即代表worker本身,所以当线程启动时,会执行worker类里面的 run() 方法.
    this.thread = getThreadFactory().newThread(this);
}
public void run() {
    runWorker(this); //调用// ThreadPoolExecutor.runWorker()
}

// Thread.class
public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

6. runWorker(this)

// ThreadPoolExecutor.class
final void runWorker(Worker w) {
	Thread wt = Thread.currentThread();
	Runnable task = w.firstTask; //获取当前线程任务
	w.firstTask = null; 
	// 把 status 设置为 0,允许中断;与Worker构造那里的setState(-1)遥相呼应
	w.unlock(); // allow interrupts
	boolean completedAbruptly = true;
	try {
	    while (task != null || (task = getTask()) != null) {
	    	// 此处加锁是为了避免任务运行期间,其他线程调用 shutdown 方法关闭线程池中正在执行任务的线程。
	        w.lock();
	        // 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();  // 执行任务,这里的 task 是 execute() 方法中传入的 Runnable 对象。
	            } 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);  // 配合 beforeExecute(wt, task) 可以计算出每个任务的耗时。
	            }
	        } finally {
	            task = null;
	            // Worker.completedTasks 字段表示每个线程处理的 task 数量,可以作为线程使用程度的参考。
	            w.completedTasks++;
	            w.unlock(); //释放当前线程的独占锁
	        }
	    }
	    completedAbruptly = false;
	} finally {
		// 注意:执行到这里说明 task == null 并且 getTask()返回 null。
		// 说明当前线程池线程数过多(任务过少,导致不是每个线程都能从队列中获取数据。),因此可以把多于corePoolSize 数量的工作线程干掉。
	    processWorkerExit(w, completedAbruptly);
	}
}

protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }
protected void terminated() { }

小结:

在分析之前,需要了解一下线程池在几种 runState 状态的特点。
RUNNING:接收新任务并处理队列中的任务。
SHUTDOWN:不接收新任务,但会处理队列中的任务。
STOP: 不接收新任务,不处理队列中的任务,并中断正在处理的任务。
TIDYING:所有任务已终止,workerCount为0,处于TIDYING状态的线程将调用钩子方法terminated()。
TERMINATED:terminated()方法完成。

// 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();
}

上面这部分代码的判断逻辑分为两种情况:

  1. runStateAtLeast(ctl.get(), STOP) && !wt.isInterrupted()
    提示: 线程池STOP 状态下,既不接收新的 task,也不处理队列中的 task;
    在STOP状态下,如果当前线程不阻断 (即 wt.isInterrupted() = false),则需要调用 wt.interrupt() 去阻断当前线程处理任何 task;

  2. Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()
    当执行到这个判断逻辑时,代表当前线程池的状态还未达到 STOP 状态,则需要确保线程没有中断(因为当前线程需要保持处理task的能力)。

    1. 第1步:执行 Thread.interrupted() 会清除当前线程的阻断状态(确保线程非阻断)。
    2. 第2步:执行 runStateAtLeast(ctl.get(), STOP) 是为了再次验证线程池的状态,因为可能会有 shutdownNow() 的情况。
    3. 当线程池状态又满足第2步时(即要满足STOP状态下线程池的特性),由于第1步调用 Thread.interrupted() 会清除线程阻断的状态,所以 wt.isInterrupted() 必然返回 false,所以会重新执行 wt.interrupt() 进行阻断。

7. getTask()

// ThreadPoolExecutor.class
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.
        // 以下返回 null 的场景请参考下面小结部分的第 2,3 两点。
        // 1.线程池状态 >= STOP
        // 2.线程池状态 >= SHUTDOWN,且队列为空。
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }

		// 获取当前的线程个数
        int wc = workerCountOf(c);

        // Are workers subject to culling?
        // 线程的超时机制:如果线程处于闲置状态,且闲置时间超过了设置的等待时间(keepAliveTime),线程就会被销毁。
        // 如果allowCoreThreadTimeOut=true:会作用于所有线程(核心线程 + 非核心线程)
        // 如果allowCoreThreadTimeOut=false:仅作用于非核心线程
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

		// 下面返回 null 的场景,请参考下面小结部分的第 1,4 两点。
		// 第1点:当 wc > maximumPoolSize 满足条件时,wc > 1 也成立;
		// 第4点:获取 task 超时时,需要判断当前队列是否为空;队列不为空,则线程池至少要存在一个线程;队列为空,则线程池可以不存在线程;
        if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
        	// 从队列中获取Runnable元素,会超时的,使用 poll(); 不会超时的,使用 take();
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
            if (r != null)
                return r; 
            timedOut = true;  // 这种一定是超时导致的,所以timedOut设置为true
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

小结:

getTask() 方法返回 null 的情况主要有以下4点:

  1. 当前线程总数超过了 maximumPoolSize 限制;

    正常情况下,线程池的线程数量是不会超过 maximumPoolSize 大小的,但是 ThreadPoolExecutor.setMaximumPoolSize() 可以动态设置新的最大线程数,所以就可能存在当前线程数超过 maximumPoolSize 的情况)。

  2. 线程池的状态处于STOP。

  3. 线程池的状态处于SHUTDOWN,且队列为空。

    为何线程池状态处于SHUTDOWN时,需要对队列进行判空?
    线程池为SHUTDOWN状态时,还是会继续处理队列中的数据,即队列非空的情况下,仍能从 getTask(), 方法中取出 task,而非 null ,所以需要对队列进行判空。

  4. 超时的条件( 1.当 worker 所在线程获取 task 超时(即队列为空)时,2.或者线程闲置超时要中止时);

    1. 如果任务队列非空,要保证当前 worker 线程不是线程池中最后一个线程;
    2. 如果任务队列为空,当前线程是线程池中的最后一个线程也无妨(即任务队列为空,当前 worker 线程关闭就关闭了,没影响) ;

8. processWorkerExit(Worker w, boolean completedAbruptly)

// ThreadPoolExecutor.class
private void processWorkerExit(Worker w, boolean completedAbruptly) {
	//任务是否是突然完成啦,完成就将工作线程数量-1
    //如果completedAbruptly=true,则说明线程执行时出现异常,需要将workerCount数量减一
    //如果completedAbruptly=false,则说明在 getTask() 方法中已经对workerCount进行减一,这里不用再减
	if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        decrementWorkerCount();

    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        completedTaskCount += w.completedTasks; //计算线程池完成的任务总个数
        workers.remove(w); //从 workers 集合中删除当前 worker 线程
    } finally {
        mainLock.unlock();
    }

    tryTerminate(); //尝试把线程池的状态设置为 TERMINATED

    int c = ctl.get();
    if (runStateLessThan(c, STOP)) { //满足条件的线程池状态:RUNNING、SHUTDOWN
        if (!completedAbruptly) {
            int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
            if (min == 0 && ! workQueue.isEmpty())
                min = 1;
            if (workerCountOf(c) >= min)
                return; // replacement not needed
        }
         //新建 worker 线程的条件:
         //1.当前线程数小于核心线程数
         //2.任务队列不为空但没有运行的线程了(允许核心线程超时的情况下)
        addWorker(null, false);
    }
}

9. tryTerminate()

// ThreadPoolExecutor.class
final void tryTerminate() {
   	for (;;) {
        int c = ctl.get();
        //处于下面三种任意一种情况,不能把线程池的状态设为 TERMINATED
        //1.RUNNING状态:不能终止线程池。
        //2.TIDYING、TERMINATED状态:说明线程池已经处于正在终止的路上,不用再终止了。
        //3.SHUTDOWN状态:且任务队列不为空,也不能终止线程池。
        if (isRunning(c) ||
            runStateAtLeast(c, TIDYING) ||
            (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
            return;
        //工作线程数不等于0时,中断一个空闲的工作线程
        if (workerCountOf(c) != 0) { // Eligible to terminate
            interruptIdleWorkers(ONLY_ONE);
            return;
        }

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
        	//设置线程池状态为TIDYING,如果设置成功,则调用 terminated() 方法
            if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                try {
                    terminated(); //线程池状态变为TERMINATED后
                } finally {
                    ctl.set(ctlOf(TERMINATED, 0)); //将线程池状态设置为TERMINATED
                    termination.signalAll();
                }
                return;
            }
        } finally {
            mainLock.unlock();
        }
        // else retry on failed CAS
    }
}

10. shutdown()、shutdownNow ()

// ThreadPoolExecutor.class
public void shutdown() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        checkShutdownAccess(); //权限校验
        advanceRunState(SHUTDOWN); //设置线程池状态为 SHUTDOWN
        interruptIdleWorkers(); //中断所有空闲线程
        onShutdown(); //子类实现的钩子方法
    } finally {
        mainLock.unlock();
    }
    tryTerminate(); // 尝试设置线程池状态为 TERMINATED
}

private void interruptIdleWorkers(boolean onlyOne) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (Worker w : workers) {
            Thread t = w.thread;
            //tryLock() 判断线程是否空闲
            if (!t.isInterrupted() && w.tryLock()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                } finally {
                    w.unlock();
                }
            }
            if (onlyOne)
                break;
        }
    } finally {
        mainLock.unlock();
    }
}
public List<Runnable> shutdownNow() {
    List<Runnable> tasks;
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        checkShutdownAccess(); //权限校验
        advanceRunState(STOP); //设置线程池状态为 STOP
        interruptWorkers(); //中断所有线程
        tasks = drainQueue(); //将任务队列中的任务移动到 tasks 中
    } finally {
        mainLock.unlock();
    }
    tryTerminate(); //尝试设置线程池状态为 TERMINATED
    return tasks;
}

private void interruptWorkers() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (Worker w : workers)
            w.interruptIfStarted(); //直接执行中断
    } finally {
        mainLock.unlock();
    }
}

四、execute(Runnable) 的执行流程

执行 execute(Runnable) 方法传入的 Runnable 又是如何被执行的呢?

  1. 在执行execute(Runnable) 方法时,会将Runnable对象通过 addWorker(Runnable firstTask, boolean core) 方法传入;

  2. addWorker(Runnable firstTask, boolean core) 方法中,通过创建 Worker(Runnable firstTask) 对象将 Runnable 对象传入 Worker;在创建 Worker 对象时,会通过 ThreadFactory.newThread(this) 方法构造一个线程,此时将外部的 Runnable 传递给具体线程的 target

    // ThreadPoolExecutor.Worker.class
    Worker(Runnable firstTask) {
        setState(-1); // inhibit interrupts until runWorker
        this.firstTask = firstTask;
        // 此处newThread(this) 传入的this即代表worker本身,所以当线程启动时,会执行worker类里面的 run() 方法.
        this.thread = getThreadFactory().newThread(this);
    }
    // Thread.class
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    
  3. addWorker(Runnable firstTask, boolean core) 方法中,创建完 Worker 对象后,会获取当前线程并启动;

    // ThreadPoolExecutor.Worker.class
    private boolean addWorker(Runnable firstTask, boolean core) {
        // ...省略部分代码
        
        Worker w =  new Worker(firstTask); //只要创建了一个新的Worker,就会伴随创建一个Thread
        final Thread t = w.thread; //获取线程
         // ...省略部分代码
         if (t != null) {
             // ...省略部分代码
             if (workerAdded) {
                 t.start(); //启动线程
                 workerStarted = true;
             }
        }
        // ...省略部分代码
        return workerStarted;
    }
    
  4. 启动线程时,会执行 Thread 内的 run() 方法,在 Thread.run() 方法中,会执行 target.run() 方法,而 target 对象就是我们传入的 Worker 对象。

    // Thread.class
    public void run() {
        if (target != null) {
            target.run(); // 此处的 target 即是 Worker 对象
        }
    }
    
  5. 第4步调用了 Worker.run() 方法后,会调用 ThreadPoolExecutor.runWorker(this) 方法,在 runWorker(this) 方法中会执行从 execute(Runnable) 传递进来的 Runnable

    // ThreadPoolExecutor.Worker.class
    public void run() { 
        runWorker(this);  //
    }
    
    // ThreadPoolExecutor.class
    final void runWorker(Worker w) {
    	Thread wt = Thread.currentThread();
    	Runnable task = w.firstTask; //获取当前线程任务
    	// ...省略部分代码
        while (task != null || (task = getTask()) != null) {
    		// ...省略部分代码
    		beforeExecute(wt, task); 
    		task.run();  // 执行任务,这里的 task 是 execute() 方法中传入的 Runnable 对象。
            afterExecute(task, thrown); 
            // ...省略部分代码
        }
    }
    
    
发布了158 篇原创文章 · 获赞 26 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/Love667767/article/details/104721043