点击此处去Gitee上Clone源码下来在IDE上看效果更佳
- Executor
package java.util.concurrent;
/**
* 执行提交的可运行任务的对象。
*/
public interface Executor {
/**
* 在将来的某个时间执行给定命令。
* 根据{@code Executor}实现的判断,命令可以在新线程,池线程或调用线程中执行。
*
* @param command the runnable task
* @throws RejectedExecutionException 如果无法接受此任务,比如线程池队列满了,执行抛出异常策略
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
- ExecutorService
package java.util.concurrent;
import java.util.Collection;
import java.util.List;
/**
* 一种{@link Executor},对Executor进行了扩展。
* 提供管理终止的方法以及可以产生{@link Future}来跟踪一个或多个异步任务进度的方法。
*
* <p>
* 可以关闭{@code ExecutorService},这将导致它拒绝新任务。
* 提供了两种不同的方法来关闭{@code ExecutorService}。
* {@link #shutdown}方法将允许先前提交的任务在终止之前执行,
* 而{@link #shutdownNow}方法可防止等待的任务启动并尝试停止当前正在执行的任务。
* 终止后,执行者将没有正在执行的任务,没有正在等待执行的任务,并且无法提交新任务。
* 应该关闭未使用的{@code ExecutorService}以回收其资源
*/
public interface ExecutorService extends Executor {
/**
* 启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务。
* 如果已经关闭,则调用不会产生任何其他影响。
*
* <p>
* 此方法不等待先前提交的任务完成执行。
* 使用{@link #awaitTermination awaitTermination}可以做到这一点。
*/
void shutdown();
/**
* 尝试停止所有正在执行的任务,暂停正在等待的任务的处理,并返回正在等待执行的任务的列表。
* <p>
* 此方法不等待正在执行的任务终止。
* 使用{@link #awaitTermination awaitTermination}可以做到这一点。
* <p>
* 除了尽最大努力阻止停止处理正在执行的任务之外,没有任何保证。
* 例如,典型的实现将通过{@link Thread#interrupt}取消,因此任何无法响应中断的任务都可能永远不会终止。
*
* @return 未开始执行的任务列表
*/
List<Runnable> shutdownNow();
/**
* @return 如果此执行程序已关闭,则返回{@code true}
*/
boolean isShutdown();
/**
* 如果所有任务在关闭后都已完成,则返回{@code true}。
* 请注意,除非首先调用{@code shutdown}或{@code shutdownNow},否则{@code isTerminated}永远不会是{@code true}。
*
* @return {@code true},如果所有任务在关闭后都已完成
*/
boolean isTerminated();
/**
* 阻塞直到关闭请求后所有任务完成执行,或者发生超时,或者当前线程被中断(以先发生者为准)。
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return {@code true} 如果该执行程序终止 and {@code false} 如果终止前已超时
* @throws InterruptedException if interrupted while waiting
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 提交一个Callable,返回一个Future。
*/
<T> Future<T> submit(Callable<T> task);
/**
* 提交没有返回值的任务,如果使用Future的get方法的话,任务执行完之后得到的是result
*/
<T> Future<T> submit(Runnable task, T result);
/**
* 提交没有返回值的任务,如果使用Future的get方法的话,任务执行完之后得到的是null
*/
Future<?> submit(Runnable task);
/**
* 执行给定的所有任务, 全部完成后返回一个List<Future<T>>,
* 对于返回列表的每个元素,{@link Future#isDone}为{@code true}。
* 请注意,已完成的任务可能已正常终止,也可能引发异常。
* 如果在进行此操作时修改了给定的集合,则此方法的结果不确定。
*
* @param tasks the collection of tasks
* @param <T> the type of the values returned from the tasks
* @return 返回一个Future的List,其顺序与迭代器为给定任务列表生成的顺序相同,每个任务均已完成
* @throws InterruptedException if interrupted while waiting, in
* which case unfinished tasks are cancelled
* @throws NullPointerException if tasks or any of its elements are {@code null}
* @throws RejectedExecutionException if any task cannot be
* scheduled for execution
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
/**
* 带有超时时间的invokeAll
* for execution
*/
<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;
/**
* 带有超时时间的invokeAny
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
- AbstractExecutorService
package java.util.concurrent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* 提供{@link ExecutorService}执行方法的默认实现。
*/
public abstract class AbstractExecutorService implements ExecutorService {
/**
* 传入Runnable和value返回一个FutureTask。
*/
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
/**
* 传入Callable返回一个FutureTask。
*/
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);//调用execute
return ftask;//返回RunnableFuture
}
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;
}
/**
* the main mechanics of invokeAny.
*/
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();
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
ExecutorCompletionService<T> ecs =
new ExecutorCompletionService<T>(this);
// For efficiency, especially in executors with limited
// parallelism, check to see if previously submitted tasks are
// done before submitting more of them. This interleaving
// plus the exception mechanics account for messiness of main
// loop.
try {
// Record exceptions so that if we fail to obtain any
// result, we can throw the last exception we got.
ExecutionException ee = null;
final long deadline = timed ? System.nanoTime() + nanos : 0L;
Iterator<? extends Callable<T>> it = tasks.iterator();
// Start one task for sure; the rest incrementally
futures.add(ecs.submit(it.next()));
--ntasks;
int active = 1;
for (; ; ) {
Future<T> f = ecs.poll();
if (f == null) {
if (ntasks > 0) {
--ntasks;
futures.add(ecs.submit(it.next()));
++active;
} else if (active == 0)
break;
else if (timed) {
f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null)
throw new TimeoutException();
nanos = deadline - System.nanoTime();
} else
f = ecs.take();
}
if (f != null) {
--active;
try {
return f.get();
} catch (ExecutionException eex) {
ee = eex;
} catch (RuntimeException rex) {
ee = new ExecutionException(rex);
}
}
}
if (ee == null)
ee = new ExecutionException();
throw ee;
} finally {
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).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));
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
//遍历执行
for (Callable<T> t : tasks) {
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
execute(f);
}
//遍历get
for (int i = 0, size = futures.size(); i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
try {
f.get();
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
}
}
}
done = true;
return futures;
} finally {
if (!done)//没有完成所有的任务
//取消未完成的任务
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks)
futures.add(newTaskFor(t));
final long deadline = System.nanoTime() + nanos;
final int size = futures.size();
// Interleave time checks and calls to execute in case
// executor doesn't have any/much parallelism.
for (int i = 0; i < size; i++) {
execute((Runnable) futures.get(i));
nanos = deadline - System.nanoTime();
if (nanos <= 0L)
return futures;
}
for (int i = 0; i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
if (nanos <= 0L)
return futures;
try {
f.get(nanos, TimeUnit.NANOSECONDS);
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
} catch (TimeoutException toe) {
return futures;
}
nanos = deadline - System.nanoTime();
}
}
done = true;
return futures;
} finally {
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}
}
- ThreadPoolExecutor
package java.util.concurrent;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 一个{@link ExecutorService},它使用可能是线程池中的多个线程中的一个线程来执行每个提交的任务,
* 这些线程通常使用{@link Executors}工厂方法进行配置。
* 此类里执行任务的线程是一个{@link Worker}
*
* <p>
* 线程池解决了两个不同的问题:由于减少了每个任务的调用开销,它们通常在执行大量异步任务时提供更高的性能,
* 并且它们提供了一种方法来限制和管理执行任务集合时消耗的资源(包括线程)。
* 每个{@code ThreadPoolExecutor}还维护一些基本统计信息,例如已完成任务的数量。
*
* <p>
* {@link Executors}提供了一些线程池的实现。
*/
public class ThreadPoolExecutor extends AbstractExecutorService {
/*常用字段*/
/**
* 最大核心线程(Worker)数量。
* 核心Worker在出生(实例化)后会一直工作,直到出现以下情况
* 1.如果设置了allowCoreThreadTimeOut为true,核心Worker在空闲了一定时间后也会被开除(回收)。
* 2.核心Worker坏掉了(出现了异常),也会被开除(回收)
*/
private volatile int corePoolSize;
/**
* 最大的Worker数,超过了corePoolSize后,任务很多,核心Worker忙不过来,会招临时工,在不忙的时候就被开除
*/
private volatile int maximumPoolSize;
/**
* 空闲时间,非核心线程与allowCoreThreadTimeOut的核心线程在超过了此空闲时间后都会被回收
*/
private volatile long keepAliveTime;
/**
* 创建线程的工厂
*/
private volatile ThreadFactory threadFactory;
/**
* 内部的工作队列,任务在提交后会进入此队列,等待Worker来接任务
*/
private final BlockingQueue<Runnable> workQueue;
/**
* 在队满或关闭时调用的处理程序。
*/
private volatile RejectedExecutionHandler handler;
/**
* 默认拒绝执行处理程序
*/
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
/* 预定义的RejectedExecutionHandlers */
/**
* 让调用者线程执行此Runnable
*/
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() {
}
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
/**
* 抛出一个 {@code RejectedExecutionException}.
*/
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() {
}
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
/**
* 丢弃新来的任务
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() {
}
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
/**
* 拒绝任务的处理程序,它丢弃最旧的未处理请求,然后重试{@code execute}
*/
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() {
}
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();//丢弃最老的任务
e.execute(r);//执行新来任务
}
}
}
/*构造器,主要就是设置前面的那几个字段*/
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.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
/*常用方法*/
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. 如果正在运行的线程少于corePoolSize线程,请尝试使用给定command作为其第一个任务来启动新线程。
* 对addWorker的调用从原子上检查runState和workerCount,
* 从而通过返回false来防止在不应该添加线程的情况下发出虚假警报。
*
* 2.如果任务可以成功入队,那么我们仍然需要仔细检查是否应该添加线程(因为现有线程自上次检查后就死掉了)
* ,或者自进入此方法以来该池已关闭。
* 因此,我们重新检查状态,并在必要时回滚入队(如果已停止),或者在没有线程的情况下启动新线程。
*
* 3. 如果我们无法将任务入队,则尝试添加一个新线程。
* 如果失败,我们知道我们已关闭或已饱和,因此拒绝该任务。
*/
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))//如果处于关闭状态,则拒绝新任务
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);//没有Worker则启动一个新临时工
} else if (!addWorker(command, false))//队列已满,尝试添加临时工
//临时工添加失败,拒绝任务
reject(command);
}
/*核心::Worker*/
/**
* Class Worker主要维护线程运行任务的中断控制状态,以及其他次要簿记。
* 此类适时地扩展了AbstractQueuedSynchronizer以简化获取和释放围绕每个任务执行的锁。
*/
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable {
/**
* This class will never be serialized, but we provide a
* serialVersionUID to suppress a javac warning.
*/
private static final long serialVersionUID = 6138294804551838833L;
/**
* 内部的线程
*/
final Thread thread;
/**
* 要运行的初始任务。可能为null。
*/
Runnable firstTask;
/**
* 每个线程任务计数器
*/
volatile long completedTasks;
/**
* 使用给定的第一个任务和ThreadFactory中的线程创建。
*/
Worker(Runnable firstTask) {
setState(-1); // 禁止中断,直到runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/**
* 将主运行循环委托给外部runWorker
*/
public void run() {
runWorker(this);
}
// 锁方法 methods
//
// 值0代表解锁状态。
// 值1表示锁定状态。
//当前线程是否独占资源
protected boolean isHeldExclusively() {
return getState() != 0;
}
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
//状态设置为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) {
}
}
}
}
/*
* runWorker与addWorker
*/
/**
* 此方法在Worker的run方法里调用
*/
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
//task会一直循环调用getTask()获取新任务,没有新任务就阻塞
//线程池在进入关闭状态后,getTask返回空,Worker不需要再工作了
while (task != null || (task = getTask()) != null) {
w.lock();//此处加锁是为了防止调用shutdown方法时,正在工作的Worker被中断
// 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钩子函数
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钩子函数
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
/**
* 根据当前配置设置执行阻塞或定时等待任务,或者如果此工作程序由于以下任何原因而必须退出,则返回null:
* 1. 工人数量超过了maximumPoolSize (由于调用setMaximumPoolSize).
* 2. 池已停止。
* 3. 池已关闭并且队列为空。
* 4. 该工作程序等待任务超时,并且在定时等待之前和之后,超时的工作线程都将终止
* (即{@code allowCoreThreadTimeOut || workerCount> corePoolSize}),
* 并且如果队列为非空,此工作程序一定不是池中的最后一个线程。
*
* @return task,如果Worker必须退出,则返回null,在这种情况下workerCount递减
*/
private Runnable getTask() {
boolean timedOut = false; //最后的poll()是否超时?
for (; ; ) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();//减少worker数量
return null;
}
int wc = workerCountOf(c);
// 工人会被淘汰吗?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
//减少worker数量
//当前(orker数量大于maximumPoolSize或者超时)
if ((wc > maximumPoolSize || (timed && timedOut))
//并且(worker数量大于1或者workQueue为空)
&& (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;
}
}
}
/**
* 检查是否可以针对当前池状态和给定的边界(核心或最大值)添加新的工作程序。
* <p>
* 如果是这样,则会相应地调整工作程序计数,并且如果可能,
* 会创建并启动一个新的工作程序,并运行firstTask作为其第一个任务。
* <p>
* 如果池已停止或有资格关闭,则此方法返回false。
* <p>
* 如果在询问时线程工厂未能创建线程,它也会返回false。
* <p>
* 如果线程创建失败(由于线程工厂返回null或由于异常(通常是Thread.start()中的OutOfMemoryError)),
* 我们将彻底回滚。
*
* @param firstTask 新线程应首先运行的任务(如果没有,则为null)。
* 当线程数少于corePoolSize线程(在这种情况下,我们总是启动一个)或
* 队列已满(在这种情况下,我们必须绕过队列)时,
* 使用初始的第一个任务(在execute()方法中)创建工作程序以绕过队列。
* 最初,空闲线程通常是通过prestartCoreThread创建的,或者用于替换其他垂死的工作线程。
* @param core 是否是核心线程
* @return true if successful
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (; ; ) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
//判断是否能增加新Worker
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))
//计数+1成功则进入下一步
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);
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()) // 检查此线程是否已经被启动
throw new IllegalThreadStateException();
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 {
if (!workerStarted)
//启动失败
addWorkerFailed(w);
}
return workerStarted;
}
/**
* 启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务。
* 如果已经关闭,则调用不会产生任何其他影响。
* 此方法不等待先前提交的任务完成执行。使用awaitTermination可以做到这一点。
*/
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//安全检查,检查调用方是否有权限关闭线程池
checkShutdownAccess();
//修改状态为SHUTDOWN
advanceRunState(SHUTDOWN);
interruptIdleWorkers();//中断空闲的Worker,既没有lock的Worker
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
tryTerminate();
}
/**
* 尝试停止所有正在执行的任务,暂停正在等待的任务的处理,并返回正在等待执行的任务的列表。
* <p>
* 此方法不等待正在执行的任务终止。
* 使用{@link #awaitTermination awaitTermination}可以做到这一点。
* <p>
* 除了尽最大努力阻止停止处理正在执行的任务之外,没有任何保证。
* 例如,典型的实现将通过{@link Thread#interrupt}取消,因此任何无法响应中断的任务都可能永远不会终止。
*
* @return 未开始执行的任务列表
*/
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();//中断所有的Worker
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
return tasks;
}
public boolean isShutdown() {
return !isRunning(ctl.get());
}
/**
* 如果此执行程序在关闭或shutdownNow之后正在终止但尚未完全终止,则返回true。
*/
public boolean isTerminating() {
int c = ctl.get();
return !isRunning(c) && runStateLessThan(c, TERMINATED);
}
public boolean isTerminated() {
return runStateAtLeast(ctl.get(), TERMINATED);
}
/**
* 阻塞直到关闭请求后所有任务完成执行,或者发生超时,或者当前线程被中断(以先发生者为准)。
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return {@code true} 如果该执行程序终止 and {@code false} 如果终止前已超时
* @throws InterruptedException if interrupted while waiting
*/
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;
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}
public void setThreadFactory(ThreadFactory threadFactory) {
if (threadFactory == null)
throw new NullPointerException();
this.threadFactory = threadFactory;
}
public ThreadFactory getThreadFactory() {
return threadFactory;
}
public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
if (handler == null)
throw new NullPointerException();
this.handler = handler;
}
public RejectedExecutionHandler getRejectedExecutionHandler() {
return handler;
}
public void setCorePoolSize(int corePoolSize) {
if (corePoolSize < 0)
throw new IllegalArgumentException();
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
if (workerCountOf(ctl.get()) > corePoolSize)
interruptIdleWorkers();//开除闲置员工
else if (delta > 0) {
/**
* 我们真的不知道“需要”多少个新线程。
* 作为一种启发式方法,请预先启动足够的新工作线程(最大为新的核心大小)以处理队列中的当前任务数,
* 但是如果在此期间队列变空则停止。
*/
int k = Math.min(delta, workQueue.size());
while (k-- > 0 && addWorker(null, true)) {
if (workQueue.isEmpty())
break;
}
}
}
public int getCorePoolSize() {
return corePoolSize;
}
/**
* 启动一个核心线程,使其闲置地等待工作。
* 这将覆盖仅在执行新任务时启动核心线程的默认策略。
* 如果所有核心线程均已启动,则此方法将返回{@code false}。
*
* @return {@code true} if a thread was started
*/
public boolean prestartCoreThread() {
return workerCountOf(ctl.get()) < corePoolSize &&
addWorker(null, true);
}
/**
* 启动所有核心线程,使它们空闲地等待工作。
* 这将覆盖仅在执行新任务时启动核心线程的默认策略。
*
* @return the number of threads started
*/
public int prestartAllCoreThreads() {
int n = 0;
while (addWorker(null, true))
++n;
return n;
}
/**
* @return {@code true} if core threads are allowed to time out
*/
public boolean allowsCoreThreadTimeOut() {
return allowCoreThreadTimeOut;
}
/**
* @param value {@code true} if should time out, else {@code false}
*/
public void allowCoreThreadTimeOut(boolean value) {
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
if (value != allowCoreThreadTimeOut) {
allowCoreThreadTimeOut = value;
if (value)
interruptIdleWorkers();//开除闲置员工
}
}
public void setMaximumPoolSize(int maximumPoolSize) {
if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
this.maximumPoolSize = maximumPoolSize;
if (workerCountOf(ctl.get()) > maximumPoolSize)
interruptIdleWorkers();//开除闲置员工
}
public int getMaximumPoolSize() {
return maximumPoolSize;
}
public void setKeepAliveTime(long time, TimeUnit unit) {
if (time < 0)
throw new IllegalArgumentException();
if (time == 0 && allowsCoreThreadTimeOut())
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
long keepAliveTime = unit.toNanos(time);
long delta = keepAliveTime - this.keepAliveTime;
this.keepAliveTime = keepAliveTime;
if (delta < 0)
interruptIdleWorkers();
}
public long getKeepAliveTime(TimeUnit unit) {
return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
}
/* User-level queue utilities */
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}
public boolean remove(Runnable task) {
boolean removed = workQueue.remove(task);
tryTerminate(); // 如果SHUTDOWN且现在为空
return removed;
}
/**
* 尝试从工作队列中删除所有已取消的Future。
* 此方法可用作存储回收操作,对功能没有其他影响。
* 已取消的任务永远不会执行,但可能会在工作队列中累积,直到工作线程可以主动将其删除为止。
* 而是调用此方法尝试立即将其删除。但是,如果存在其他线程的干扰,此方法可能无法删除任务。
*/
public void purge() {
final BlockingQueue<Runnable> q = workQueue;
try {
Iterator<Runnable> it = q.iterator();
while (it.hasNext()) {
Runnable r = it.next();
if (r instanceof Future<?> && ((Future<?>) r).isCancelled())
it.remove();
}
} catch (ConcurrentModificationException fallThrough) {
// Take slow path if we encounter interference during traversal.
// Make copy for traversal and call remove for cancelled entries.
// The slow path is more likely to be O(N*N).
for (Object r : q.toArray())
if (r instanceof Future<?> && ((Future<?>) r).isCancelled())
q.remove(r);
}
tryTerminate(); // In case SHUTDOWN and now empty
}
/* Statistics */
/**
* 返回池中的当前线程数。
*/
public int getPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Remove rare and surprising possibility of
// isTerminated() && getPoolSize() > 0
return runStateAtLeast(ctl.get(), TIDYING) ? 0
: workers.size();
} finally {
mainLock.unlock();
}
}
/**
* 返回正在主动执行任务的线程的大概数量。
*/
public int getActiveCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int n = 0;
for (Worker w : workers)
if (w.isLocked())
++n;
return n;
} finally {
mainLock.unlock();
}
}
/**
* 返回池中曾经同时存在的最大线程数。
*/
public int getLargestPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
return largestPoolSize;
} finally {
mainLock.unlock();
}
}
/**
* 返回计划执行的任务总数。由于任务和线程的状态在计算过程中可能会动态变化,因此返回的值只是一个近似值。
*/
public long getTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers) {
n += w.completedTasks;
if (w.isLocked())
++n;
}
return n + workQueue.size();
} finally {
mainLock.unlock();
}
}
/**
* 返回已完成执行的任务的大概总数。
* 由于任务和线程的状态在计算过程中可能会动态变化,因此返回的值仅是一个近似值,而在连续的调用中不会降低。
*/
public long getCompletedTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers)
n += w.completedTasks;
return n;
} finally {
mainLock.unlock();
}
}
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;//整理状态,shutDown和shutDownNow后进入
private static final int TERMINATED = 3 << COUNT_BITS;
// Packing and unpacking ctl
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;
}
/*
* Bit field accessors that don't require unpacking ctl.
* These depend on the bit layout and on workerCount being never negative.
*/
private static boolean runStateLessThan(int c, int s) {
return c < s;
}
private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}
private static boolean isRunning(int c) {
return c < SHUTDOWN;
}
/**
* Attempts to CAS-increment the workerCount field of ctl.
*/
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
/**
* Attempts to CAS-decrement the workerCount field of ctl.
*/
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
/**
* Decrements the workerCount field of ctl. This is called only on
* abrupt termination of a thread (see processWorkerExit). Other
* decrements are performed within getTask.
*/
private void decrementWorkerCount() {
do {
} while (!compareAndDecrementWorkerCount(ctl.get()));
}
/**
* Lock held on access to workers set and related bookkeeping.
* While we could use a concurrent set of some sort, it turns out
* to be generally preferable to use a lock. Among the reasons is
* that this serializes interruptIdleWorkers, which avoids
* unnecessary interrupt storms, especially during shutdown.
* Otherwise exiting threads would concurrently interrupt those
* that have not yet interrupted. It also simplifies some of the
* associated statistics bookkeeping of largestPoolSize etc. We
* also hold mainLock on shutdown and shutdownNow, for the sake of
* ensuring workers set is stable while separately checking
* permission to interrupt and actually interrupting.
*/
private final ReentrantLock mainLock = new ReentrantLock();
/**
* Set containing all worker threads in pool. Accessed only when
* holding mainLock.
*/
private final HashSet<Worker> workers = new HashSet<Worker>();
/**
* Wait condition to support awaitTermination
*/
private final Condition termination = mainLock.newCondition();
/**
* 跟踪曾经达到过的达到的最大池大小。
*/
private int largestPoolSize;
/**
* Counter for completed tasks. Updated only on termination of
* worker threads. Accessed only under mainLock.
*/
private long completedTaskCount;
/*
* All user control parameters are declared as volatiles so that
* ongoing actions are based on freshest values, but without need
* for locking, since no internal invariants depend on them
* changing synchronously with respect to other actions.
*/
/**
* If false (default), core threads stay alive even when idle.
* If true, core threads use keepAliveTime to time out waiting
* for work.
*/
private volatile boolean allowCoreThreadTimeOut;
/**
* Permission required for callers of shutdown and shutdownNow.
* We additionally require (see checkShutdownAccess) that callers
* have permission to actually interrupt threads in the worker set
* (as governed by Thread.interrupt, which relies on
* ThreadGroup.checkAccess, which in turn relies on
* SecurityManager.checkAccess). Shutdowns are attempted only if
* these checks pass.
* <p>
* All actual invocations of Thread.interrupt (see
* interruptIdleWorkers and interruptWorkers) ignore
* SecurityExceptions, meaning that the attempted interrupts
* silently fail. In the case of shutdown, they should not fail
* unless the SecurityManager has inconsistent policies, sometimes
* allowing access to a thread and sometimes not. In such cases,
* failure to actually interrupt threads may disable or delay full
* termination. Other uses of interruptIdleWorkers are advisory,
* and failure to actually interrupt will merely delay response to
* configuration changes so is not handled exceptionally.
*/
private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");
/* The context to be used when executing the finalizer, or null. */
private final AccessControlContext acc;
/*
* Methods for setting control state
*/
/**
* Transitions runState to given target, or leaves it alone if
* already at least the given target.
*
* @param targetState the desired state, either SHUTDOWN or STOP
* (but not TIDYING or TERMINATED -- use tryTerminate for that)
*/
private void advanceRunState(int targetState) {
for (; ; ) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
/**
* Transitions to TERMINATED state if either (SHUTDOWN and pool
* and queue empty) or (STOP and pool empty). If otherwise
* eligible to terminate but workerCount is nonzero, interrupts an
* idle worker to ensure that shutdown signals propagate. This
* method must be called following any action that might make
* termination possible -- reducing worker count or removing tasks
* from the queue during shutdown. The method is non-private to
* allow access from ScheduledThreadPoolExecutor.
*/
final void tryTerminate() {
for (; ; ) {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && !workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
/*
* Methods for controlling interrupts to worker threads.
*/
/**
* If there is a security manager, makes sure caller has
* permission to shut down threads in general (see shutdownPerm).
* If this passes, additionally makes sure the caller is allowed
* to interrupt each worker thread. This might not be true even if
* first check passed, if the SecurityManager treats some threads
* specially.
*/
private void checkShutdownAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
}
}
/**
* Interrupts all threads, even if active. Ignores SecurityExceptions
* (in which case some threads may remain uninterrupted).
*/
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
}
/**
* Interrupts threads that might be waiting for tasks (as
* indicated by not being locked) so they can check for
* termination or configuration changes. Ignores
* SecurityExceptions (in which case some threads may remain
* uninterrupted).
*
* @param onlyOne If true, interrupt at most one worker. This is
* called only from tryTerminate when termination is otherwise
* enabled but there are still other workers. In this case, at
* most one waiting worker is interrupted to propagate shutdown
* signals in case all threads are currently waiting.
* Interrupting any arbitrary thread ensures that newly arriving
* workers since shutdown began will also eventually exit.
* To guarantee eventual termination, it suffices to always
* interrupt only one idle worker, but shutdown() interrupts all
* idle workers so that redundant workers exit promptly, not
* waiting for a straggler task to finish.
*/
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
Thread t = w.thread;
if (!t.isInterrupted() && w.tryLock()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
/**
* Common form of interruptIdleWorkers, to avoid having to
* remember what the boolean argument means.
*/
private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}
private static final boolean ONLY_ONE = true;
/*
* Misc utilities, most of which are also exported to
* ScheduledThreadPoolExecutor
*/
/**
* Invokes the rejected execution handler for the given command.
* Package-protected for use by ScheduledThreadPoolExecutor.
*/
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
/**
* Performs any further cleanup following run state transition on
* invocation of shutdown. A no-op here, but used by
* ScheduledThreadPoolExecutor to cancel delayed tasks.
*/
void onShutdown() {
}
/**
* State check needed by ScheduledThreadPoolExecutor to
* enable running tasks during shutdown.
*
* @param shutdownOK true if should return true if SHUTDOWN
*/
final boolean isRunningOrShutdown(boolean shutdownOK) {
int rs = runStateOf(ctl.get());
return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
}
/**
* Drains the task queue into a new list, normally using
* drainTo. But if the queue is a DelayQueue or any other kind of
* queue for which poll or drainTo may fail to remove some
* elements, it deletes them one by one.
*/
private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
ArrayList<Runnable> taskList = new ArrayList<Runnable>();
q.drainTo(taskList);
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}
/**
* 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);
decrementWorkerCount();
tryTerminate();
} finally {
mainLock.unlock();
}
}
/**
* Performs cleanup and bookkeeping for a dying worker. Called
* only from worker threads. Unless completedAbruptly is set,
* assumes that workerCount has already been adjusted to account
* for exit. This method removes thread from worker set, and
* possibly terminates the pool or replaces the worker if either
* it exited due to user task exception or if fewer than
* corePoolSize workers are running or queue is non-empty but
* there are no workers.
*
* @param w the worker
* @param completedAbruptly if the worker died due to user exception
*/
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)
return; // replacement not needed
}
addWorker(null, false);
}
}
// Public constructors and methods
/**
* Invokes {@code shutdown} when this executor is no longer
* referenced and it has no threads.
*/
protected void finalize() {
SecurityManager sm = System.getSecurityManager();
if (sm == null || acc == null) {
shutdown();
} else {
PrivilegedAction<Void> pa = () -> {
shutdown();
return null;
};
AccessController.doPrivileged(pa, acc);
}
}
/**
* 与prestartCoreThread相同,除了安排即使corePoolSize为0,也至少启动一个线程。
*/
void ensurePrestart() {
int wc = workerCountOf(ctl.get());
if (wc < corePoolSize)
addWorker(null, true);
else if (wc == 0)
addWorker(null, false);
}
/**
* Returns a string identifying this pool, as well as its state,
* including indications of run state and estimated worker and
* task counts.
*
* @return a string identifying this pool, as well as its state
*/
public String toString() {
long ncompleted;
int nworkers, nactive;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
ncompleted = completedTaskCount;
nactive = 0;
nworkers = workers.size();
for (Worker w : workers) {
ncompleted += w.completedTasks;
if (w.isLocked())
++nactive;
}
} finally {
mainLock.unlock();
}
int c = ctl.get();
String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
(runStateAtLeast(c, TERMINATED) ? "Terminated" :
"Shutting down"));
return super.toString() +
"[" + rs +
", pool size = " + nworkers +
", active threads = " + nactive +
", queued tasks = " + workQueue.size() +
", completed tasks = " + ncompleted +
"]";
}
/* Extension hooks */
/**
* 在给定线程中执行给定Runnable之前调用的方法。
*/
protected void beforeExecute(Thread t, Runnable r) {
}
/**
* 给定Runnable执行完成时调用的方法。
*/
protected void afterExecute(Runnable r, Throwable t) {
}
/**
* 执行程序终止时调用的方法。
*/
protected void terminated() {
}
}
}