目录
本篇博客重点讲解ThreadPoolExecutor的三个基础设施类AbstractExecutorService、FutureTask和ExecutorCompletionService的实现细节,AbstractExecutorService实现了ExecutorService的大部分接口,子类只需实现excute方法和shutdown相关方法即可;FutureTask是RunnableFuture接口的主要实现,该接口是Runnable和Future的包装类接口,会执行Runnable对应的run方法,调用方可以通过Future接口获取任务的执行状态和结果;ExecutorCompletionService是帮助获取多个RunnableFuture任务的执行结果的工具类,基于FutureTask执行完成时的回调方法done实现的。
一、AbstractExecutorService
1、定义
ThreadPoolExecutor的类继承关系如下:
其中ExecutorService的子类如下:
右上角带S的表示内部类,我们重点关注ThreadPoolExecutor,ScheduledThreadPoolExecutor和ForkJoinPool三个类的实现,后面两个类会在后面的博客中逐一探讨。
Executor包含的方法如下:
ExecutorService包含的方法如下:
上述接口方法中涉及的Callable接口的定义如下:
该接口也是表示一个执行任务,跟常见的Runnable接口的区别在于call方法有返回值而run方法没有返回值。
Future表示某个任务的执行结果,其定义的方法如下:
其子类比较多,如下:
后面会将涉及的子类逐一探讨的。 AbstractExecutorService基于Executor接口的excute方法实现了大部分的ExecutorService的接口,子类只需要重点实现excute方法和shutdown相关方法即可,下面来分析其具体的实现。
2、submit
//Runnable接口方法没有返回值,但是可以通过Future判断任务是否执行完成
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
//因为Runnable的run方法没有返回值,所以如果run方法正常执行完成,其结果就是result
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;
}
//都是返回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);
}
3、invokeAll
//执行完成tasks中所有的任务,如果有一个抛出异常,则取消掉剩余的任务
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 {
//遍历tasks中的任务将其转换成RunnableFuture,然后提交到线程池执行
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);
}
}
//逻辑同上,不过加了等待时间限制,所有的任务的累计时间不能超过指定值,如果超时直接返回Future列表
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;