Java线程池ThreadPoolExecutor源码分析
class DirectExecutor implements Executor{
public void execute(Runnable r){
r.run();// 这里不是用的new Thread(r).start(),也就是说没有启动任何一个新的线程。
}
}
每个任务提交进来后,直接启动一个新的线程来执行这个任务:
class ThreadPerTaskExecutor implements Executor{
public void execute(Runnable r){
new Thread(r).start(); // 每个任务都用一个新的线程来执行
}
}
class SerialExecutor implements Executor
{
// 任务队列
final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
// 这个才是真正的执行器
final Executor executor;
// 当前正在执行的任务
Runnable active;
// 初始化的时候,指定执行器
SerialExecutor(Executor executor)
{
this.executor = executor;
}
// 添加任务到线程池: 将任务添加到任务队列,scheduleNext 触发执行器去任务队列取任务
public synchronized void execute(final Runnable r)
{
tasks.offer(new Runnable()
{
public void run()
{
try
{
r.run();
}
finally
{
scheduleNext();
}
}
});
if (active == null)
{
scheduleNext();
}
}
protected synchronized void scheduleNext()
{
if ((active = tasks.poll()) != null)
{
// 具体的执行转给真正的执行器 executor
executor.execute(active);
}
}
}
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InteruptedException;
<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;
}
一般我们定义一个线程池的时候,往往都是使用这个接口:
public abstract class AbstractExecutorService implements ExecutorService {
// RunnableFuture 是用于获取执行结果的,我们常用它的子类 FutureTask
// 下面两个 newTaskFor 方法用于将我们的任务包装成 FutureTask 提交到线程池中执行
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
// 提交任务
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
// 1. 将任务包装成 FutureTask
RunnableFuture<Void> ftask = newTaskFor(task, null);
// 2. 交给执行器执行,execute 方法由具体的子类来实现
// 前面也说了,FutureTask 间接实现了Runnable 接口。
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
// 1. 将任务包装成 FutureTask
RunnableFuture<T> ftask = newTaskFor(task, result);
// 2. 交给执行器执行
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
// 1. 将任务包装成 FutureTask
RunnableFuture<T> ftask = newTaskFor(task);
// 2. 交给执行器执行
execute(ftask);
return ftask;
}
// 此方法目的:将 tasks 集合中的任务提交到线程池执行,任意一个线程执行完后就可以结束了
// 第二个参数 timed 代表是否设置超时机制,超时时间为第三个参数,
// 如果 timed 为 true,同时超时了还没有一个线程返回结果,那么抛出 TimeoutException 异常
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
boolean timed, long nanos)
throws InterruptedException, ExecutionException, TimeoutException {
if (tasks == null)
throw new NullPointerException();
// 任务数
int ntasks = tasks.size();
if (ntasks == 0)
throw new IllegalArgumentException();
//
List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
// ExecutorCompletionService 不是一个真正的执行器,参数 this 才是真正的执行器
// 它对执行器进行了包装,每个任务结束后,将结果保存到内部的一个 completionQueue 队列中
// 这也是为什么这个类的名字里面有个 Completion 的原因吧。
ExecutorCompletionService<T> ecs =
new ExecutorCompletionService<T>(this);
try {
// 用于保存异常信息,此方法如果没有得到任何有效的结果,那么我们可以抛出最后得到的一个异常
ExecutionException ee = null;
long lastTime = timed ? System.nanoTime() : 0;
Iterator<? extends Callable<T>> it = tasks.iterator();
// 首先先提交一个任务,后面的任务到下面的 for 循环一个个提交
futures.add(ecs.submit(it.next()));
// 提交了一个任务,所以任务数量减 1
--ntasks;
// 正在执行的任务数(提交的时候 +1,任务结束的时候 -1)
int active = 1;
for (;;) {
// ecs 上面说了,其内部有一个 completionQueue 用于保存执行完成的结果
// BlockingQueue 的 poll 方法不阻塞,返回 null 代表队列为空
Future<T> f = ecs.poll();
// 为 null,说明刚刚提交的第一个线程还没有执行完成
// 在前面先提交一个任务,加上这里做一次检查,也是为了提高性能
if (f == null) {
if (ntasks > 0) {
--ntasks;
futures.add(ecs.submit(it.next()));
++active;
}
// 这里是 else if,不是 if。这里说明,没有任务了,同时 active 为 0 说明
// 任务都执行完成了。其实我也没理解为什么这里做一次 break?
// 因为我认为 active 为 0 的情况,必然从下面的 f.get() 返回了
// 2018-02-23 感谢读者 newmicro 的 comment,
// 这里的 active == 0,说明所有的任务都执行失败,那么这里是 for 循环出口
else if (active == 0)
break;
// 这里也是 else if。这里说的是,没有任务了,但是设置了超时时间,这里检测是否超时
else if (timed) {
// 带等待的 poll 方法
f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
// 如果已经超时,抛出 TimeoutException 异常,这整个方法就结束了
if (f == null)
throw new TimeoutException();
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
}
// 这里是 else。说明,没有任务需要提交,但是池中的任务没有完成,还没有超时(如果设置了超时)
// take() 方法会阻塞,直到有元素返回,说明有任务结束了
else
f = ecs.take();
}
/*
* 我感觉上面这一段并不是很好理解,这里简单说下。
* 1. 首先,这在一个 for 循环中,我们设想每一个任务都没那么快结束,
* 那么,每一次都会进到第一个分支,进行提交任务,直到将所有的任务都提交了
* 2. 任务都提交完成后,如果设置了超时,那么 for 循环其实进入了“一直检测是否超时”
这件事情上
* 3. 如果没有设置超时机制,那么不必要检测超时,那就会阻塞在 ecs.take() 方法上,
等待获取第一个执行结果
* 4. 如果所有的任务都执行失败,也就是说 future 都返回了,
但是 f.get() 抛出异常,那么从 active == 0 分支出去(感谢 newmicro 提出)
// 当然,这个需要看下面的 if 分支。
*/
// 有任务结束了
if (f != null) {
--active;
try {
// 返回执行结果,如果有异常,都包装成 ExecutionException
return f.get();
} catch (ExecutionException eex) {
ee = eex;
} catch (RuntimeException rex) {
ee = new ExecutionException(rex);
}
}
}// 注意看 for 循环的范围,一直到这里
if (ee == null)
ee = new ExecutionException();
throw ee;
} finally {
// 方法退出之前,取消其他的任务
for (Future<T> f : futures)
f.cancel(true);
}
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
try {
return doInvokeAny(tasks, false, 0);
} catch (TimeoutException cannotHappen) {
assert false;
return null;
}
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return doInvokeAny(tasks, true, unit.toNanos(timeout));
}
// 执行所有的任务,返回任务结果。
// 先不要看这个方法,我们先想想,其实我们自己提交任务到线程池,也是想要线程池执行所有的任务
// 只不过,我们是每次 submit 一个任务,这里以一个集合作为参数提交
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
// 这个很简单
for (Callable<T> t : tasks) {
// 包装成 FutureTask
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
// 提交任务
execute(f);
}
for (Future<T> f : futures) {
if (!f.isDone()) {
try {
// 这是一个阻塞方法,直到获取到值,或抛出了异常
// 这里有个小细节,其实 get 方法签名上是会抛出 InterruptedException 的
// 可是这里没有进行处理,而是抛给外层去了。此异常发生于还没执行完的任务被取消了
f.get();
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
}
}
}
done = true;
// 这个方法返回,不像其他的场景,返回 List<Future>,其实执行结果还没出来
// 这个方法返回是真正的返回,任务都结束了
return futures;
} finally {
// 为什么要这个?就是上面说的有异常的情况
if (!done)
for (Future<T> f : futures)
f.cancel(true);
}
}
// 带超时的 invokeAll,我们找不同吧
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null || unit == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks)
futures.add(newTaskFor(t));
long lastTime = System.nanoTime();
Iterator<Future<T>> it = futures.iterator();
// 每提交一个任务,检测一次是否超时
while (it.hasNext()) {
execute((Runnable)(it.next()));
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
// 超时
if (nanos <= 0)
return futures;
}
for (Future<T> f : futures) {
if (!f.isDone()) {
if (nanos <= 0)
return futures;
try {
// 调用带超时的 get 方法,这里的参数 nanos 是剩余的时间,
// 因为上面其实已经用掉了一些时间了
f.get(nanos, TimeUnit.NANOSECONDS);
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
} catch (TimeoutException toe) {
return futures;
}
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
}
}
done = true;
return futures;
} finally {
if (!done)
for (Future<T> f : futures)
f.cancel(true);
}
}
}
//高3位表示线程池状态, 后29位表示线程个数,记录线程池状态和线程数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
////线程数量统计位数29 Integer.SIZE=32
private static final int COUNT_BITS = Integer.SIZE - 3;
//容量 000 11111111111111111111111111111
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;
//获取运行状态(获取前3位)
private static int runStateOf(int c) { return c & ~CAPACITY; }
//获取线程个数(获取后29位)
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc;
RUNNING = 0:接受新任务并且处理阻塞队列里的任务
SHUTDOWN = 1:拒绝新任务但是处理阻塞队列里的任务
STOP = 2:拒绝新任务并且抛弃阻塞队列里的任务同时会中断正在处理的任务
TIDYING :所有任务都执行完(包含阻塞队列里面任务)当前线程池活动线程为0,将要调用terminated方法
TERMINATED = 3:终止状态。terminated方法调用完成以后的状态
线程池状态转换:
//任务队列 private final BlockingQueue<Runnable> workQueue; //工作者集合 private final HashSet<Worker> workers = new HashSet<Worker>(); //线程达到的最大值 private int largestPoolSize; //已完成任务总数 private long completedTaskCount; //线程工厂 private volatile ThreadFactory threadFactory; //拒绝策略 private volatile RejectedExecutionHandler handler; //闲置线程存活时间 private volatile long keepAliveTime; //是否允许核心线程超时 private volatile boolean allowCoreThreadTimeOut; //核心线程数量 private volatile int corePoolSize; //最大线程数量 private volatile int maximumPoolSize; //默认拒绝策略 private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
//核心构造器
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) {
throw new IllegalArgumentException();
}
if (workQueue == null || threadFactory == null || handler == null) {
throw new NullPointerException();
}
this.corePoolSize = corePoolSize; //设置核心线程数量
this.maximumPoolSize = maximumPoolSize; //设置最大线程数量
this.workQueue = workQueue; //设置存放任务队列
this.keepAliveTime = unit.toNanos(keepAliveTime); //设置非核心线程存活时间
this.threadFactory = threadFactory; //设置用来生产线程的工厂
this.handler = handler; //设置不能再放入任务时候执行的拒绝策略
}
ThreadPoolExecutor有多个构造器,所有的构造器都会调用上面的核心构造器。通过核心构造器我们可以为线程池设置不同的参数,由此线程池也能表现出不同的特性。
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
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;
}
submit 方法中,参数是 Runnable 类型(也有Callable 类型),这个参数不是用于new Thread(runnable).start()中的,也就是说此处的这个参数不是用于启动线程的,这里指的是任务,任务要做的事情是 run()方法里面定义的或 Callable 中的 call() 方法里面定义的。
-
调用submit方法,传入Runnable或者Callable对象
-
判断传入的对象是否为null,为null则抛出异常,不为null继续流程
-
将传入的对象转换为RunnableFuture对象
-
执行execute方法,传入RunnableFuture对象
-
返回RunnableFuture对象
//核心执行方法
public void execute(Runnable command) {
if (command == null) throw new NullPointerException();
int c = ctl.get();
//线程数若小于corePoolSize则新建核心工作者
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) return;
c = ctl.get();
}
//否则将任务放到任务队列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//若不是running状态则将该任务从队列中移除
if (!isRunning(recheck) && remove(command)) {
//成功移除后再执行拒绝策略
reject(command);
//若线程数为0则新增一个非核心线程
}else if (workerCountOf(recheck) == 0) {
addWorker(null, false);
}
//若队列已满则新增非核心工作者
}else if (!addWorker(command, false)) {
//若新建非核心线程失败则执行拒绝策略
reject(command);
}
}
-
调用execute方法,传入Runable对象
-
判断传入的对象是否为null,为null则抛出异常,不为null继续流程
-
获取当前线程池的状态和线程个数变量
-
判断当前线程数是否小于核心线程数,是走流程5,否则走流程6
-
添加线程数,添加成功则结束,失败则重新获取当前线程池的状态和线程个数变量,
-
判断线程池是否处于RUNNING状态,是则添加任务到阻塞队列,否则走流程10,添加任务成功则继续流程7
-
重新获取当前线程池的状态和线程个数变量
-
重新检查线程池状态,不是运行状态则移除之前添加的任务,有一个false走流程9,都为true则走流程11
-
检查线程池线程数量是否为0,否则结束流程,是调用addWorker(null, false),然后结束
-
调用!addWorker(command, false),为true走流程11,false则结束
-
调用拒绝策略reject(command),结束
//工作者类
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
//关联线程
final Thread thread;
//初始任务
Runnable firstTask;
//完成任务数
volatile long completedTasks;
//构造器
Worker(Runnable firstTask) {
//抑制中断直到runWorker
setState(-1);
//设置初始任务
this.firstTask = firstTask;
//设置关联线程
this.thread = getThreadFactory().newThread(this);
}
public void run() {
runWorker(this);
}
//判断是否占有锁, 0代表未占用, 1代表已占用
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(); }
//中断关联线程
void interruptIfStarted() {
Thread t;
//将活动线程和闲置线程都中断
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
//ignore
}
}
}
}
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
//只有以下两种情况会继续添加线程
//1.状态为running
//2.状态为shutdown,首要任务为空,但任务队列中还有任务
if (rs >= SHUTDOWN && !(rs == SHUTDOWN && firstTask == null && !workQueue.isEmpty())) {
return false;
}
for (;;) {
int wc = workerCountOf(c);
//以下三种情况不继续添加线程:
//1.线程数大于线程池总容量
//2.当前线程为核心线程,且核心线程数达到corePoolSize
//3.当前线程非核心线程,且总线程达到maximumPoolSize
if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) {
return false;
}
//否则继续添加线程, 先将线程数加一
if (compareAndIncrementWorkerCount(c)) {
//执行成功则跳过外循环
break retry;
}
//CAS操作失败再次检查线程池状态
c = ctl.get();
//如果线程池状态改变则继续执行外循环
if (runStateOf(c) != rs) {
continue retry;
}
//否则表明CAS操作失败是workerCount改变, 继续执行内循环
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
final ReentrantLock mainLock = this.mainLock;
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
mainLock.lock();
try {
int c = ctl.get();
int rs = runStateOf(c);
if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) {
//如果线程已经开启则抛出异常
if (t.isAlive()) 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) {
addWorkerFailed(w);
}
}
return workerStarted;
}
//工作线程
final void runWorker(Worker w) {
//获取当前工作线程
Thread wt = Thread.currentThread();
//获取工作者的初始任务
Runnable task = w.firstTask;
//将工作者的初始任务置空
w.firstTask = null;
//将同步状态从-1设为0
w.unlock();
boolean completedAbruptly = true;
try {
//初始任务不为空则执行初始任务, 否则从队列获取任务
while (task != null || (task = getTask()) != null) {
//确保获取到任务后才加锁
w.lock();
//若状态大于等于stop, 保证当前线程被中断
//若状态小于stop, 保证当前线程未被中断
//在清理中断状态时可能有其他线程在修改, 所以会再检查一次
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();
} 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();
}
}
//设置该线程为正常完成任务
completedAbruptly = false;
} finally {
//执行完所有任务后将线程删除
processWorkerExit(w, completedAbruptly);
}
}
//从任务队列中获取任务
private Runnable getTask() {
//上一次获取任务是否超时
boolean timedOut = false;
retry:
//在for循环里自旋
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
//以下两种情况会将工作者数减为0并返回null,并直接使该线程终止:
//1.状态为shutdown并且任务队列为空
//2.状态为stop, tidying或terminated
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
boolean timed;
//判断是否要剔除当前线程
for (;;) {
int wc = workerCountOf(c);
//以下两种情况会在限定时间获取任务:
//1.允许核心线程超时
//2.线程数大于corePoolSize
timed = allowCoreThreadTimeOut || wc > corePoolSize;
//以下两种情况不执行剔除操作:
//1.上次任务获取未超时
//2.上次任务获取超时, 但没要求在限定时间获取
if (wc <= maximumPoolSize && !(timedOut && timed)) {
break;
}
//若上次任务获取超时, 且规定在限定时间获取, 则将线程数减一
if (compareAndDecrementWorkerCount(c)) {
//CAS操作成功后直接返回null
return null;
}
//CAS操作失败后再次检查状态
c = ctl.get();
//若状态改变就从外层循环重试
if (runStateOf(c) != rs) {
continue retry;
}
//否则表明是workerCount改变, 继续在内循环重试
}
try {
//若timed为true, 则在规定时间内返回
//若timed为false, 则阻塞直到获取成功
//注意:闲置线程会一直在这阻塞
Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
//获取任务不为空则返回该任务
if (r != null) {
return r;
}
//否则将超时标志设为true
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
工作线程在while循环里不断的通过getTask方法来从任务队列中获取任务,我们看一下getTask方法是怎样获取任务的。进入第一个for循环之后有一个if判断,从这里我们可以看到,如果线程池状态为shutdown,会继续消费任务队列里面的任务;如果线程池状态为stop,则停止消费任务队列里剩余的任务。进入第二个for循环后会给timed变量赋值,由于allowCoreThreadTimeOut变量默认是false,所以timed的值取决于线程数是否大于corePoolSize,小于为false,大于则为true。从任务队列里面获取任务的操作在try块里面,如果timed为true,则调用poll方法进行定时获取;如果timed为flase,则调用take方法进行阻塞获取。也就是说默认情况下,如果线程数小于corePoolSize,则调用take方法进行阻塞获取,即使任务队列为空,工作线程也会一直等待;如果线程数大于corePoolSize,则调用poll方法进行定时获取,在keepAliveTime时间内获取不到任务则会返回null,对应的工作线程也会被移除,但线程数会保持在corePoolSize上。当然如果设置allowCoreThreadTimeOut为true,则会一直通过调用poll方法来从任务队列中获取任务,如果任务队列长时间为空,则工作线程会减少至0。
//删除工作线程
private void processWorkerExit(Worker w, boolean completedAbruptly) {
//若非正常完成则将线程数减为0
if (completedAbruptly) {
decrementWorkerCount();
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//统计完成的任务总数
completedTaskCount += w.completedTasks;
//在这将工作线程移除
workers.remove(w);
} finally {
mainLock.unlock();
}
//尝试终止线程池
tryTerminate();
//再次检查线程池状态
int c = ctl.get();
//若状态为running或shutdown, 则将线程数恢复到最小值
if (runStateLessThan(c, STOP)) {
//线程正常完成任务被移除
if (!completedAbruptly) {
//允许核心线程超时最小值为0, 否则最小值为核心线程数
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
//如果任务队列还有任务, 则保证至少有一个线程
if (min == 0 && !workQueue.isEmpty()) {
min = 1;
}
//若线程数大于最小值则不新增了
if (workerCountOf(c) >= min) {
return;
}
}
//新增工作线程
addWorker(null, false);
}
}
//平缓关闭线程池
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//检查是否有关闭的权限
checkShutdownAccess();
//将线程池状态设为shutdown
advanceRunState(SHUTDOWN);
//中断闲置的线程
interruptIdleWorkers();
//对外提供的钩子
onShutdown();
} finally {
mainLock.unlock();
}
//尝试终止线程池
tryTerminate();
}
//立刻关闭线程池
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;
}
final void tryTerminate() {
for (;;) {
int c = ctl.get();
//以下两种情况终止线程池,其他情况直接返回:
//1.状态为stop
//2.状态为shutdown且任务队列为空
if (isRunning(c) || runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && !workQueue.isEmpty())) {
return;
}
//若线程不为空则中断一个闲置线程后直接返回
if (workerCountOf(c) != 0) {
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//将状态设置为tidying
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
//线程池终止后做的事情
terminated();
} finally {
//将状态设置为终止状态(TERMINATED)
ctl.set(ctlOf(TERMINATED, 0));
//唤醒条件队列所有线程
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
//若状态更改失败则再重试
}
}
public interface ThreadFactory {
Thread newThread(Runnable r);
}
Executors.defaultThreadFactory()实现
public static ThreadFactory defaultThreadFactory() {
return new DefaultThreadFactory();
}
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);//原子类,线程池编号
private final ThreadGroup group;//线程组
private final AtomicInteger threadNumber = new AtomicInteger(1);//线程数目
private final String namePrefix;//为每个创建的线程添加的前缀
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();//取得线程组
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);//真正创建线程的地方,设置了线程的线程组及线程名
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)//默认是正常优先级
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}

浙公网安备 33010602011771号