接口定义
// 需要传递一个Callable的集合,返回Future的List。
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws 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); // 将超时时间转为nanos
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); // 创建futures集合,大小和tasks一样
boolean done = false;
try {
for (Callable<T> t : tasks)
futures.add(newTaskFor(t)); // 循环遍历tasks,添加到futures集合中,注意这儿是有序的
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++) { // 到这儿说明还没有超时,遍历futures
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);
}
}
就这么多吧,很容易理解的。