Java常用线程池体系及源码解读
结构图:
接口说明
- Executor:线程池顶级接口;
- ExecutorService:线程池次级接口,对Executor做了一些扩展,增加了一些功能;
- ScheduledExecutorService:对ExecutorService做了一些扩展,增加一些定时任务相关的功能;
- AbstractExecutorService:抽象类,运用模板方法设计模式实现了一部分方法;
- ThreadPoolExecutor:普通线程池类,包含最基本的一些线程池操作相关的方法实现;
- ScheduledThreadPoolExecutor:定时任务线程池类,用于实现定时任务相关功能;
- ForkJoinPool:新型线程池类,java7中新增的线程池类,基于工作窃取理论实现,运用于大任务拆小任务,任务无限多的场景;
- Excutors:线程池工具类,定义了一些快速实现线程池的方法
1.Executer
线程池顶级接口,定义了一个执行无返回值任务的方法
public interface Executor {
/**
* 执行无返回值任务
* 根据Executor的实现判断,可能是在新线程、线程池、线程调用中执行
*/
void execute ( Runnable command);
}
2.ExecutorService
/**
* 线程池次级接口,对Executor做了一些扩展,增加了一些功能
*/
public interface ExecutorService extends Executor {
/**
* 关闭线程池,不再接受新任务,但已经提交的任务会执行完成
*/
void shutdown();
/**
* 立即关闭线程池,尝试停止正在运行的任务,未执行的任务将不再执行
* 被迫停止及未执行的任务将以列表的形式返回
*/
List<Runnable> shutdownNow();
/**
* 检查线程池是否已关闭
*/
boolean isShutdown();
/**
* 检查线程池是否已终止,只有在shutdown()或shutdownNow()之后调用才有可能为true
*/
boolean isTerminated();
/**
* 在指定时间内线程池达到终止状态了才会返回true
* @throws InterruptedException if interrupted while waiting
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 执行有返回值的任务,任务的返回值为task.call()的结果
*/
<T> Future<T> submit(Callable<T> task);
/**
* 执行有返回值的任务,任务的返回值为这里传入的result
* 当然只有当任务执行完成了调用get()时才会返回
*/
<T> Future<T> submit(Runnable task, T result);
/**
* 执行有返回值的任务,任务的返回值为null
* 当然只有当任务执行完成了调用get()时才会返回
*/
Future<?> submit(Runnable task);
/**
* 批量执行任务,只有当这些任务都完成了这个方法才会返回
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
/**
* 在指定时间内批量执行任务,未执行完成的任务将被取消
* 这里的timeout是所有任务的总时间,不是单个任务的时间
*/
<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;
}
3.ScheduledExecutorService
public interface ScheduledExecutorService extends ExecutorService {
/**
* 在指定的延时后执行一次
* @param delay 从现在开始到延时执行的时间
* @param unit 延时时间单位
*/
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
/**
* 在指定的延时后执行一次
* @param delay 从现在开始到延时执行的时间
* @param unit 延时时间单位
*/
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);
/**
* 在指定延时后首先执行一次,随后按照周期执行,不包含任务执行的时间
* 参数:
* initialDelay 第一次执行时间
* 第一次执行时间:initialDelay
* 第二次执行时间:initialDelay + period
* 第三次执行时间:initialDelay + 2 * period
* @param command 线程执行体
* @param initialDelay 第一次执行时间
* @param period 两次执行的时间间隔,不包含上一个任务执行时间
* @param unit 延时时间单位
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
/**
* 在指定延时后首先执行一次,随后按照指定延时重复执行,相当于包含任务执行的时间
* @param command 线程执行体
* @param initialDelay 第一次延时执行的时间
* @param delay 一个任务执行结束到另一个任务开始执行之间的延迟,延时以上一个任务结束开始计算
* @param unit 延时时间单位
*/
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
}
4.AbstractExecutorService
public abstract class AbstractExecutorService implements ExecutorService {
/**
* 将Runnable包装成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);
}
/**
* 将Runnable执行线程且没有返回值
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future<?> submit(Runnable task) {
//如果为null则抛出空指针
if (task == null) throw new NullPointerException();
//包装任务为Future
RunnableFuture<Void> ftask = newTaskFor(task, null);
//将任务交给执行器,可能会抛出异常,真正执行的是ThreadPoolExecutor.execute方法,后续会有源码讲解
execute(ftask);
return ftask;
}
/**
* 将Runnable执行线程且带返回值
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public <T> Future<T> submit(Runnable task, T result) {
//如果为null则抛出空指针
if (task == null) throw new NullPointerException();
//包装任务为Future,带返回值
RunnableFuture<T> ftask = newTaskFor(task, result);
//将任务交给执行器,可能会抛出异常,真正执行的是ThreadPoolExecutor.execute方法,后续会有源码讲解
execute(ftask);
return ftask;
}
/**
* 将Callable执行线程,返回Future。且带返回值
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public <T> Future<T> submit(Callable<T> task) {
//如果为null则抛出空指针
if (task == null) throw new NullPointerException();
//包装任务为Future泛型
RunnableFuture<T> ftask = newTaskFor(task);
//将任务交给执行器,可能会抛出异常,真正执行的是ThreadPoolExecutor.execute方法,后续会有源码讲解
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 {
//如果为null则抛出空指针
if (tasks == null)
throw new NullPointerException();
//任务数量
int ntasks = tasks.size();
//任务数为0,抛出异常
if (ntasks == 0)
throw new IllegalArgumentException();
//创建任务量大小的集合
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
//this是当前的Executor的执行器
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 {
//记录异常,会抛出
ExecutionException ee = null;
//记录执行到当前的纳秒时间,如果设置了超时,则计算任务执行时间,如果是0则不设置超时时间
final long deadline = timed ? System.nanoTime() + nanos : 0L;
//获取任务的迭代器
Iterator<? extends Callable<T>> it = tasks.iterator();
// 第一个任务交给ecs执行
futures.add(ecs.submit(it.next()));
//记录的任务数减一
--ntasks;
//上边执行了一个任务,则激活任务为1
int active = 1;
//执行死循环
for (;;) {
//ecs是否执行完,完成后返回null
Future<T> f = ecs.poll();
if (f == null) {
//任务数大于0,说明还有其他任务在执行
if (ntasks > 0) {
//记录的任务数减一
--ntasks;
//下一个任务交给ecs执行
futures.add(ecs.submit(it.next()));
//激活任务数加一
++active;
}
//激活数为0,则所有任务执行完成,直接跳出死循环
else if (active == 0)
break;
else if (timed) {
//设置ecs超时时间
f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null)
throw new TimeoutException();
//真正执行的时间,上边nanos+系统纳秒时间,这里又减系统纳秒时间,
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 {
//取消所有futures中的任务
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 {
//遍历任务,1.创建的future添加到集合中,2.执行任务
for (Callable<T> t : tasks) {
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
execute(f);
}
//遍历集合中的future
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 {
//将所有任务添加到Future集合总
for (Callable<T> t : tasks)
futures.add(newTaskFor(t));
//计算设置超时时长的纳秒时间
final long deadline = System.nanoTime() + nanos;
final int size = futures.size();
// 执行任务
for (int i = 0; i < size; i++) {
execute((Runnable)futures.get(i));
nanos = deadline - System.nanoTime();
//nanos小于0说明超时了,直接返回future集合
if (nanos <= 0L)
return futures;
}
for (int i = 0; i < size; i++) {
Future<T> f = futures.get(i);
//任务没执行完
if (!f.isDone()) {
//nanos小于0说明超时了,直接返回future集合
if (nanos <= 0L)
return futures;
try {
//等待执行的future是否执行完成
f.get(nanos, TimeUnit.NANOSECONDS);
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
} catch (TimeoutException toe) {
//说明等待超时,需要直接返回future集合
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);
}
}
}