线程池相关
源码:
package java.util.concurrent;
import java.util.*;
public abstract class AbstractExecutorService implements ExecutorService {
/**
* 为给定可运行任务和默认值返回一个RunnableFuture
* 参数:
* runnable - 将被包装的可运行任务
* value - 用于所返回的将来任务的默认值
* 返回:
* 一个 RunnableFuture,在运行的时候,它将运行底层可运行任务,作为Future任务,它将生成给定值作为其结果,并为底层任务提供取消操作。
*/
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
/**
* 为给定可调用任务返回一个RunnableFuture。
* 参数:
* callable - 将包装的可调用任务
* 返回:
* 一个RunnableFuture,在运行的时候,它将调用底层可调用任务,作为Future任务,它将生成可调用的结果作为其结果,并为底层任务提供取消操作。
*/
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
/**
* 提交一个Runnable任务用于执行,并返回一个表示该任务的Future。
* 该Future的get方法在成功完成时将会返回null
*
* 方法指定者:接口 ExecutorService 中的 submit
* 参数:task - 要提交的任务
* 返回:表示任务等待完成的 Future
*/
public Future<?> submit(Runnable task) {
if (task == null)//校验参数
throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);//创建一个RunnableFuture对象
execute(ftask);//调用继承至ExecutorService接口的execute方法
return ftask;//返回等待任务完成的Future
}
/**
* 提交一个Runnable任务用于执行,并返回一个表示该任务的Future。
* 该Future的get方法在成功完成时将会返回给定的结果。
*
* 方法指定者:接口 ExecutorService 中的 submit
* 参数:task - 要提交的任务
* 返回:表示任务等待完成的 Future
*/
public <T> Future<T> submit(Runnable task, T result) {
if (task == null)//校验参数
throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);//创建一个RunnableFuture对象
execute(ftask);//调用继承至ExecutorService接口的execute方法
return ftask;//返回等待任务完成的Future
}
/**
* 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的Future。
* 该Future的get方法在成功完成时将会返回该任务的结果。
*
* 方法指定者:接口 ExecutorService 中的 submit
* 参数:task - 要提交的任务
* 返回:表示任务等待完成的 Future
*/
public <T> Future<T> submit(Callable<T> task) {
if (task == null)//校验参数
throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);//创建一个RunnableFuture对象
execute(ftask);//调用继承至ExecutorService接口的execute方法
return ftask;//返回等待任务完成的Future
}
/**
* 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);
//为了提高效率:检查先前提交的任务是否在提交更多的任务之前完成。
try {
//记录异常,如果我们不能获得任何结果,我们可以抛出我们得到的最后一个异常。
ExecutionException ee = null;
final long deadline = timed ? System.nanoTime() + nanos : 0L;
Iterator<? extends Callable<T>> it = tasks.iterator();
//先开始一个任务; 其余的是渐进式的
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);
}
}
/**
* 执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。
* 一旦正常或异常返回后,则取消尚未完成的任务。
* 如果此操作正在进行时修改了给定的collection,则此方法的结果是不确定的。
*
* 方法指定者:接口ExecutorService中的invokeAny
* 参数:tasks - 任务 collection
* 返回:某个任务返回的结果
* 抛出:
* InterruptedException - 如果等待时发生中断
* ExecutionException - 如果没有任务成功完成
*/
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;
}
}
/**
* 执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。
* 一旦正常或异常返回后,则取消尚未完成的任务。
* 如果此操作正在进行时修改了给定的collection,则此方法的结果是不确定的。
*
* 方法指定者:接口ExecutorService中的invokeAny
* 参数:
* tasks - 任务 collection
* timeout - 最长等待时间
* unit - timeout 参数的时间单位
* 返回:某个任务返回的结果
* 抛出:
* InterruptedException - 如果等待时发生中断
* ExecutionException - 如果没有任务成功完成
* TimeoutException - 如果在所有任务成功完成之前给定的超时期满
*/
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return doInvokeAny(tasks, true, unit.toNanos(timeout));//执行上述的私有方法
}
/**
* 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的Future列表。
* 返回列表的所有元素的 Future.isDone()为true。注意,可以正常地或通过抛出异常来终止已完成任务。
* 如果正在进行此操作时修改了给定的collection,则此方法的结果是不确定的。
*
* 方法指定者:接口ExecutorService中的invokeAll
* 参数:
* tasks - 任务 collection
* 返回:
* 表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同,每个任务都已完成。
* 抛出:
* InterruptedException - 如果等待时发生中断,在这种情况下取消尚未完成的任务。
*/
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);
}
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列表。
* 返回列表的所有元素的Future.isDone()为 true。一旦返回后,即取消尚未完成的任务。
* 注意,可以正常地或通过抛出异常来终止 已完成 任务。如果此操作正在进行时修改了给定的collection,则此方法的结果是不确定的。
* 指定者:接口ExecutorService中的invokeAll
* 参数:
* tasks - 任务 collection
* timeout - 最长等待时间
* unit - timeout 参数的时间单位
* 返回:
* 表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。
* 如果操作未超时,则已完成所有任务。
* 如果确实超时了,则某些任务尚未完成。
* 抛出:
* InterruptedException - 如果等待时发生中断,在这种情况下取消尚未完成的任务
*/
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();
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);
}
}
}
类 AbstractExecutorService
已实现的接口:
已知子类:
此类使用 newTaskFor 返回的 RunnableFuture
实现 submit、invokeAny 和 invokeAll 方法,默认情况下,RunnableFuture
是此包中提供的 FutureTask
类。例如,submit(Runnable) 的实现创建了一个关联 RunnableFuture 类,该类将被执行并返回。子类可以重写 newTaskFor 方法,以返回 FutureTask 之外的 RunnableFuture 实现。
扩展示例。以下是一个类的简要介绍,该类定制 ThreadPoolExecutor
使用 CustomTask 类替代默认 FutureTask:
public class CustomThreadPoolExecutor extends ThreadPoolExecutor { static class CustomTask<V> implements RunnableFuture<V> {...} protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) { return new CustomTask<V>(c); } protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) { return new CustomTask<V>(r, v); } // ... add constructors, etc. }
方法摘要
| invokeAll(Collection<? extends Callable<T>> tasks) 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。 | |
| invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) 执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表。 | |
| invokeAny(Collection<? extends Callable<T>> tasks) 执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。 | |
| invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) 执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。 | |
protected
| newTaskFor(Callable<T> callable) 为给定可调用任务返回一个 RunnableFuture。 | |
protected
| newTaskFor(Runnable runnable, T value) 为给定可运行任务和默认值返回一个 RunnableFuture。 | |
| submit(Callable<T> task) 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。 | |
Future<?> | submit(Runnable task) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。 | |
| submit(Runnable task, T result) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。 |
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
从接口 java.util.concurrent.ExecutorService 继承的方法
awaitTermination, isShutdown, isTerminated, shutdown, shutdownNow
从接口 java.util.concurrent.Executor 继承的方法
newTaskFor
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable,T value)
为给定可运行任务和默认值返回一个 RunnableFuture。
参数:
runnable
- 将被包装的可运行任务
value
- 用于所返回的将来任务的默认值
返回:
一个 RunnableFuture,在运行的时候,它将运行底层可运行任务,作为 Future 任务,它将生成给定值作为其结果,并为底层任务提供取消操作。
newTaskFor
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable)
为给定可调用任务返回一个 RunnableFuture。
参数:
callable
- 将包装的可调用任务
返回:
一个 RunnableFuture,在运行的时候,它将调用底层可调用任务,作为 Future 任务,它将生成可调用的结果作为其结果,并为底层任务提供取消操作。
submit
public Future<?> submit(Runnable task)
从接口 ExecutorService
复制的描述
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在 成功 完成时将会返回 null。
指定者:
接口 ExecutorService
中的 submit
参数:
task
- 要提交的任务
返回:
表示任务等待完成的 Future
submit
public <T> Future<T> submit(Runnable task, T result)
从接口 ExecutorService
复制的描述
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功完成时将会返回给定的结果。
指定者:
接口 ExecutorService
中的 submit
参数:
task
- 要提交的任务
result
- 返回的结果
返回:
表示任务等待完成的 Future
submit
public <T> Future<T> submit(Callable<T> task)
从接口 ExecutorService
复制的描述
提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。该 Future 的 get 方法在成功完成时将会返回该任务的结果。
如果想立即阻塞任务的等待,则可以使用 result = exec.submit(aCallable).get(); 形式的构造。
注:Executors
类包括了一组方法,可以转换某些其他常见的类似于闭包的对象,例如,将 PrivilegedAction
转换为 Callable
形式,这样就可以提交它们了。
指定者:
接口 ExecutorService
中的 submit
参数:
task
- 要提交的任务
返回:
表示任务等待完成的 Future
invokeAny
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException
从接口 ExecutorService
复制的描述
执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。一旦正常或异常返回后,则取消尚未完成的任务。如果此操作正在进行时修改了给定的 collection,则此方法的结果是不确定的。
指定者:
接口 ExecutorService
中的 invokeAny
参数:
tasks
- 任务 collection
返回:
某个任务返回的结果
抛出:
InterruptedException
- 如果等待时发生中断
ExecutionException
- 如果没有任务成功完成
invokeAny
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
从接口 ExecutorService
复制的描述
执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。一旦正常或异常返回后,则取消尚未完成的任务。如果此操作正在进行时修改了给定的 collection,则此方法的结果是不确定的。
指定者:
接口 ExecutorService
中的 invokeAny
参数:
tasks
- 任务 collection
timeout
- 最长等待时间
unit
- timeout 参数的时间单位
返回:
某个任务返回的结果
抛出:
InterruptedException
- 如果等待时发生中断
ExecutionException
- 如果没有任务成功完成
TimeoutException
- 如果在所有任务成功完成之前给定的超时期满
invokeAll
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException
从接口 ExecutorService
复制的描述
执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone()
为 true。注意,可以正常地或通过抛出异常来终止 已完成 任务。如果正在进行此操作时修改了给定的 collection,则此方法的结果是不确定的。
指定者:
接口 ExecutorService
中的 invokeAll
参数:
tasks
- 任务 collection
返回:
表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同,每个任务都已完成。
抛出:
InterruptedException
- 如果等待时发生中断,在这种情况下取消尚未完成的任务。
invokeAll
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException
从接口 ExecutorService
复制的描述
执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone()
为 true。一旦返回后,即取消尚未完成的任务。注意,可以正常地或通过抛出异常来终止 已完成 任务。如果此操作正在进行时修改了给定的 collection,则此方法的结果是不确定的。
指定者:
接口 ExecutorService
中的 invokeAll
参数:
tasks
- 任务 collection
timeout
- 最长等待时间
unit
- timeout 参数的时间单位
返回:
表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。如果操作未超时,则已完成所有任务。如果确实超时了,则某些任务尚未完成。
抛出:
InterruptedException
- 如果等待时发生中断,在这种情况下取消尚未完成的任务
实现原理
AbstractExecutorService对ExecutorService的执行任务类型的方法提供了一个默认实现。这些方法包括submit,invokeAny和InvokeAll。
注意的是来自Executor接口的execute方法是未被实现,execute方法是整个体系的核心,所有的任务都是在这个方法里被真正执行的,因此该方法的不同实现会带来不同的执行策略。
这个在分析ThreadPoolExecutor和ScheduledThreadPoolExecutor就能看出来。
首先来看submit方法,它的基本逻辑是这样的:
1. 生成一个任务类型和Future接口的包装接口RunnableFuture的对象
2. 执行任务
3. 返回future。
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(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
因为submit支持Callable和Runnable两种类型的任务,因此newTaskFor方法有两个重载方法:
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
Callable和Runnable的区别在于前者带返回值,也就是说Callable=Runnable+返回值。
因此java中提供了一种adapter,把Runnable+返回值转换成Callable类型。这点可以在newTaskFor中的FutureTask类型的构造函数的代码中看到:
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
public FutureTask(Runnable runnable, V result) {
sync = new Sync(Executors.callable(runnable, result));
}
以下是Executors.callable方法的代码:
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
那么RunnableAdapter的代码就很好理解了,它是一个Callable的实现,call方法的实现就是执行Runnable的run方法,然后返回那个value。
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
接下来先说说较为简单的invokeAll:
1. 为每个task调用newTaskFor方法生成得到一个既是Task也是Future的包装类对象的List
2. 循环调用execute执行每个任务
3. 再次循环调用每个Future的get方法等待每个task执行完成
4. 最后返回Future的list。
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 {
// 为每个task生成包装对象
for (Callable<T> t : tasks)
futures.add(newTaskFor(t));
long lastTime = System.nanoTime();
// 循环调用execute执行每个方法
// 这里因为设置了超时时间,所以每次执行完成后
// 检查是否超时,超时了就直接返回future集合
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 {
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);
}
}
最后说说invokeAny,它的难点在于只要一个任务执行成功就要返回,并且会取消其他任务,也就是说重点在于找到第一个执行成功的任务。
因为两个invokeAny方法都是调用doInvokeAny方法,下面是doInvokeAny的代码分析:
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负责执行任务,后面调用用poll返回第一个执行结果
ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this);
// 这里出于效率的考虑,每次提交一个任务之后,就检查一下有没有执行完成的任务
try {
ExecutionException ee = null;
long lastTime = timed ? System.nanoTime() : 0;
Iterator<? extends Callable<T>> it = tasks.iterator();
// 先提交一个任务
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();
// 这里的更新不可少,因为这个Future可能是执行失败的情况,那么还需要再次等待下一个结果,超时的设置还是需要用到。
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
}
// 没有设置超时,并且所有任务都被提交了,则一直等到第一个执行结果出来
else
f = ecs.take();
}
// 有返回结果了,尝试从future中获取结果,如果失败了,那么需要接着等待下一个执行结果
if (f != null) {
--active;
try {
return f.get();
} catch (ExecutionException eex) {
ee = eex;
} catch (RuntimeException rex) {
ee = new ExecutionException(rex);
}
}
}
// ExecutorCompletionService执行时发生错误返回了全是null的future
if (ee == null)
ee = new ExecutionException();
throw ee;
} finally {
// 尝试取消所有的任务(对于已经完成的任务没有影响)
for (Future<T> f : futures)
f.cancel(true);
}
}
当所有的任务被提交后,任务执行返回的Future会被依次添加到一个BlockingQueue中,然后找到第一个执行成功任务的方法就是从BlockingQueue取出第一个元素,这个就是doInvokeAny方法用到的ExecutorCompletionService的基本原理。
package java.util.concurrent;
public class ExecutorCompletionService<V> implements CompletionService<V> {
private final Executor executor;
private final AbstractExecutorService aes;
private final BlockingQueue<Future<V>> completionQueue;
//内部类
private class QueueingFuture extends FutureTask<Void> {
QueueingFuture(RunnableFuture<V> task) {
super(task, null);
this.task = task;
}
protected void done() { completionQueue.add(task); }
private final Future<V> task;
}
//为Callable对象实例返回一个RunnableFuture
private RunnableFuture<V> newTaskFor(Callable<V> task) {
if (aes == null)
return new FutureTask<V>(task);
else
return aes.newTaskFor(task);
}
//为Runnable对象实例返回一个RunnableFuture
private RunnableFuture<V> newTaskFor(Runnable task, V result) {
if (aes == null)
return new FutureTask<V>(task, result);
else
return aes.newTaskFor(task, result);
}
//构造器
public ExecutorCompletionService(Executor executor) {
if (executor == null)
throw new NullPointerException();
this.executor = executor;
this.aes = (executor instanceof AbstractExecutorService) ?
(AbstractExecutorService) executor : null;
this.completionQueue = new LinkedBlockingQueue<Future<V>>();
}
//构造器
public ExecutorCompletionService(Executor executor,
BlockingQueue<Future<V>> completionQueue) {
if (executor == null || completionQueue == null)
throw new NullPointerException();
this.executor = executor;
this.aes = (executor instanceof AbstractExecutorService) ?
(AbstractExecutorService) executor : null;
this.completionQueue = completionQueue;
}
//执行队列中的节点线程方法
public Future<V> submit(Callable<V> task) {
if (task == null)//检查参数
throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task);//创建一个RunnableFuture对象实例
executor.execute(new QueueingFuture(f));//执行队列中的一个节点
return f;
}
//执行队列中的线程方法
public Future<V> submit(Runnable task, V result) {
if (task == null)//检查参数
throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task, result);//创建一个RunnableFuture对象实例
executor.execute(new QueueingFuture(f));//执行队列中的一个节点
return f;
}
//获取并移除此队列的头部,在元素变得可用之前一直等待
public Future<V> take() throws InterruptedException {
return completionQueue.take();
}
//将指定元素插入此队列中,将等待可用的空间(如果有必要)
public Future<V> poll() {
return completionQueue.poll();
}
//获取并移除此队列的头部,在指定的等待时间前等待可用的元素(如果有必要)
public Future<V> poll(long timeout, TimeUnit unit)
throws InterruptedException {
return completionQueue.poll(timeout, unit);
}
}